﻿using System;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

struct VSysClock
{
    public ushort wYear;    /*19XX-20XX*/
    public byte byMonth;  /*1-12*/
    public byte byDay;    /*1-31*/
    public byte byWeek;   /*0-6  from sunday*/
    public byte byHour;   /*0-23*/
    public byte byMinute; /*0-59*/
    public byte bySecond; /*0-59*/
    public ushort wMSecond; /*0-999*/
};

struct TopoResultInfo
{
    public VSysClock curclk;
    public ushort pha;
    public ushort pwm_index;
    public ushort seq;
};


struct YYMMDDhhnn_TYPE
{

    byte nn;
    byte hh;
    byte DD;
    byte MM;
    byte YY;
};                                  /* YYMMDDhhnn结构体声明 */

struct VOLT_ITEM_TYPE
{
    byte[] Data;                             /* 电压:XXX.X V */
};

struct VOLT_ABC_TYPE
{
    VOLT_ITEM_TYPE PhaseA;                       /*  A相 */
    VOLT_ITEM_TYPE PhaseB;                       /*  B相 */
    VOLT_ITEM_TYPE PhaseC;                       /* C相 */
};                                    /* ABC相电压 */


struct CURR_ITEM_TYPE
{
    byte[] Data;                              /* 电流:XXX.XXX A */
};

struct CURR_ABC_TYPE
{
    CURR_ITEM_TYPE PhaseA;                       /* A相 */
    CURR_ITEM_TYPE PhaseB;                       /* B相 */
    CURR_ITEM_TYPE PhaseC;                       /* C相 */
};                                    /* 电流 */


struct POWER_ITEM_TYPE
{
    byte[] Data;                              /* 有功功率:XX.XXXX kW/kVar/kVA*/
};

struct POWER_0ABC_TYPE
{
    POWER_ITEM_TYPE Phase0;                      /* 总 */
    POWER_ITEM_TYPE PhaseA;                      /* A相 */
    POWER_ITEM_TYPE PhaseB;                      /* B相 */
    POWER_ITEM_TYPE PhaseC;                      /* C相 */
};                                   /* 总及ABC相有功功率 */


struct BYTE4_INT32_TYPE
{
    /*    byte Byte4 [4];
        int   SLinteger;*/
    uint ULinteger;
};                                /* 4字节联合体 */


struct VFrzInfo
{
    YYMMDDhhnn_TYPE FrzTime;                ///冻结的时间
    VOLT_ABC_TYPE CurVolt;                // 当前电压
    CURR_ABC_TYPE CurCurr;                // 当前电流	
    POWER_0ABC_TYPE CurActPower;               // 当前功率//有功
    POWER_0ABC_TYPE CurReaPower;               // 当前功率//无功
    BYTE4_INT32_TYPE Frz_FwdActTtEry;//正向有功总电能
    BYTE4_INT32_TYPE Frz_RevActTtEry;//反向有功总电能
    BYTE4_INT32_TYPE Frz_FwdRctTtEry;//正向无功总电能 ///// 组合无功1
    BYTE4_INT32_TYPE Frz_RevRctTtEry;//反向无功总电能        ///// 组合无功2 

};

namespace AnalysisMsg
{
    public partial class MainForm : Form
    {

        public static bool CurrInputDataTypeValidFlag = false;  //  判断当前输入的数据是否符合规范

        public static byte[] inputdata_hex = new byte[1000];
        public static int inputdata_length = 0;
        public static byte[] MsgDI = new byte[4];

        public static string sTmp;  //临时使用的string 变量

        public MainForm()
        {
            InitializeComponent();
        }


        public static byte BYTE2BCD(byte Value)
        {
            return (byte)((byte)((Value / 10) << 4) | (Value % 10));
        }

        public static byte BCD2BYTE(byte Value)
        {
            return (byte)((Value >> 4) * 10 + (Value & 0x0F));
        }

        public static ushort WORD2BCD(ushort Value)
        {
            return (ushort)((BYTE2BCD((byte)(Value / 100)) << 8) | (BYTE2BCD((byte)(Value % 100))));
        }

        public static ushort BCD2WORD(ushort Value)
        {
            return (ushort)((ushort)BCD2BYTE((byte)(Value >> 8)) * 100 + BCD2BYTE((byte)(Value & 0xFF)));
        }

        public static ulong DWORD2BCD(ulong Value)
        {
            return (ulong)((WORD2BCD((ushort)(Value / 10000)) << 16) | (WORD2BCD((ushort)(Value % 10000))));
        }

        public static ulong BCD2DWORD(ulong Value)
        {
            return (ulong)(BCD2WORD((ushort)(Value >> 16)) * 10000 + BCD2WORD((ushort)(Value & 0xFFFF)));
        }


        /// <summary>
        /// 计算数组加和
        /// </summary>
        /// <param name="bArr"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static byte CheckSum(byte[] bArr, int length)
        {
            ushort tmp = 0;

            for (int i = 0; i < length - 2; i++)
            {
                tmp += bArr[i];
            }

            return (byte)tmp;

        }

        /// <summary>
        /// 报文数据区 -33 
        /// </summary>
        /// <param name="bArr"></param>
        /// <param name="length"></param>
        /// <param name="start_size"></param>
        /// <returns></returns>
        public void DecodeDataBuf(byte[] bArr, int length, int start_size)
        {
            for (int i = 0; i < length; i++)
            {
                bArr[i + start_size] = (byte)(bArr[i + start_size] - 0x33);
            }
        }

        /// <summary>
        /// //将16进制字符串转化为 字节流
        /// </summary>
        /// <param name="hexStr"></param>
        /// <returns></returns>
        public static byte[] HexStringToBytes(string hexStr)
        {
            if (string.IsNullOrEmpty(hexStr))
            {
                return new byte[0];
            }

            if (hexStr.StartsWith("0x"))
            {
                hexStr = hexStr.Remove(0, 2);
            }

            var count = hexStr.Length;

            if (count % 2 == 1)
            {
                throw new ArgumentException("Invalid length of bytes:" + count);
            }

            var byteCount = count / 2;
            var result = new byte[byteCount];
            for (int ii = 0; ii < byteCount; ++ii)
            {
                var tempBytes = Byte.Parse(hexStr.Substring(2 * ii, 2), System.Globalization.NumberStyles.HexNumber);
                result[ii] = tempBytes;
            }

            return result;
        }


        /// <summary>
        /// //将字节流转化为16进制字符串
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static string BytesTohexString(byte[] bytes)
        {
            if (bytes == null || bytes.Length < 1)
            {
                return string.Empty;
            }

            var count = bytes.Length;

            var cache = new StringBuilder();
            cache.Append("0x");
            for (int ii = 0; ii < count; ++ii)
            {
                var tempHex = Convert.ToString(bytes[ii], 16).ToUpper();
                cache.Append(tempHex.Length == 1 ? "0" + tempHex : tempHex);
            }

            return cache.ToString();
        }


        /// <summary>
        /// 字符串转16进制字节数组
        /// </summary>
        /// <param name="hexString"></param>
        /// <returns></returns>
        private static byte[] strToToHexByte(string hexString)
        {
            hexString = hexString.Replace(" ", "");
            if ((hexString.Length % 2) != 0)
                hexString += " ";
            byte[] returnBytes = new byte[hexString.Length / 2];
            for (int i = 0; i < returnBytes.Length; i++)
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            return returnBytes;
        }


        /// <summary>
        /// 字节数组转16进制字符串
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static string byteToHexStr(byte[] bytes)
        {
            string returnStr = "";
            if (bytes != null)
            {
                for (int i = 0; i < bytes.Length; i++)
                {
                    returnStr += bytes[i].ToString("X2");
                }
            }
            return returnStr;
        }

        /// <summary>
        /// byte 数组转成 string 字符串
        /// </summary>
        /// <param name="bArr"></param>
        /// <param name="length"></param>
        /// <param name="start_site"></param>
        /// <returns></returns>
        public static String bytesToHexString(byte[] bArr, int length, int start_site)
        {
            string returnStr = "";
            if (bArr != null)
            {
                for (int i = 0; i < length; i++)
                {
                    returnStr += bArr[i + start_site].ToString("X2");
                }
            }
            return returnStr;

        }


        /// <summary>
        /// 输入的字符串转成byte 数组
        /// </summary>
        /// <param name="indata"></param>
        /// <returns></returns>
        public static byte[] StringToHexByte(string indata)
        {
            int i = 0;
            //bool j = false;

            char[] chs = { ' ' };
            string[] res = indata.Split(chs, options: StringSplitOptions.RemoveEmptyEntries);

            byte[] tempresult = new byte[res.Length];

            foreach (var item in res)
            {
                //Console.WriteLine(item);
                try
                {
                    tempresult[i] = byte.Parse(res[i], System.Globalization.NumberStyles.HexNumber);

                    CurrInputDataTypeValidFlag = true;
                }
                catch (System.AccessViolationException)
                {
                    Array.Clear(res, 0, res.Length);
                }
                catch (System.InvalidCastException)
                {
                    Array.Clear(res, 0, res.Length);
                    MessageBox.Show("输入格式异常");
                }
                catch (System.NullReferenceException)
                {
                    Array.Clear(res, 0, res.Length);
                    MessageBox.Show("输入格式异常1");
                }
                catch (System.ArgumentNullException)
                {// 字符串为 空
                    Array.Clear(res, 0, res.Length);
                    MessageBox.Show("输入格式异常2");
                }
                catch (System.FormatException)
                {// 输入 非 数字字符
                    Array.Clear(res, 0, res.Length);
                    MessageBox.Show("输入格式异常3");
                    CurrInputDataTypeValidFlag = false;
                }
                catch (System.OverflowException)
                {///超出 类型范围 
                    Array.Clear(res, 0, res.Length);
                    MessageBox.Show("输入格式异常4");
                }

                i++;
            }

            return tempresult;
        }


        /// <summary>
        /// 0x01 读故障和复电信息
        /// </summary>
        /// <returns></returns>
        private void DoReadGzFdInfo() //C = 0x01 读故障和复电信息
        {
            string tmpstr = null;

            this.txt_CtrlItem.Text = "读故障和复电信息";
            if (MsgDI[3] == 0xFD)
            {
                textBox1.Text +=("读复电信息");
                tmpstr = "读复电信息";
            }
            else if (MsgDI[3] == 0xFE)
            {
                textBox1.Text +=("读复电和告警信息");
                tmpstr = "读复电和告警信息";

            }
            else
            {
                textBox1.Text +=("未启用");
                tmpstr = "未启用";
            }

            textBox1.Text += tmpstr + "\r\n";
        }

        private void JudgeGzFlag(int flag, string sTmp)  //故障标志 判断
        {
            ///int tmpval = flag;
            int tureone = 0x01;

            for (int i = 0; i < 16; i++)
            {

                if ((flag & tureone) != 0)
                {
                    switch (i)
                    {
                        case 0x00:
                            sTmp += "失压";
                            break;
                        case 0x01:
                            sTmp += "欠压";
                            break;
                        case 0x02:
                            sTmp += "过压";
                            break;
                        case 0x03:
                            sTmp += "过流";
                            break;
                        case 0x04:
                            sTmp += "欠流";
                            break;
                        case 0x05:
                            sTmp += "过载";
                            break;
                        case 0x06:
                            sTmp += "反相";
                            break;
                        case 0x07:
                            sTmp += "断相";
                            break;
                        case 0x08:
                            sTmp += "剩余电流故障";
                            break;
                        case 0x09:
                            sTmp += "正常停电";
                            break;

                        default:
                            sTmp += " 无此项 ";
                            break;
                    }

                    break;
                }
                else
                {
                    tureone <<= 1;
                }
            }

            textBox1.Text += sTmp + "\r\n";
        }

        private void ChangeValFormat(byte[] Original, int site, string pha)  // 传入的数据转成实际的数值
        {
            //pha 相故障时电压
            ushort FaultPha_Vol = (ushort)(Original[site + 1] << 8 | Original[site]);
            FaultPha_Vol = BCD2WORD(FaultPha_Vol);
            double FaultPha_Vol_Val = (double)(FaultPha_Vol * 1.0) / 10;
            sTmp = pha + "相故障时电压: " + FaultPha_Vol_Val.ToString("000.0") + " V";
            textBox1.Text +=(sTmp);

            //pha 相故障前电压
            ushort BeforeFaultPha_Vol = (ushort)(Original[site + 3] << 8 | Original[site + 2]);
            BeforeFaultPha_Vol = BCD2WORD(BeforeFaultPha_Vol);
            double BeforeFaultPha_Vol_Val = (double)(BeforeFaultPha_Vol * 1.0) / 10;
            sTmp = pha + "相故障前电压: " + BeforeFaultPha_Vol_Val.ToString("000.0") + " V";
            textBox1.Text +=(sTmp);

            //pha 相故障时电流
            ulong FaultPhaA_Curr = (ulong)(Original[site + 6] << 16 | Original[site + 5] << 8 | Original[site + 4]);
            FaultPhaA_Curr = BCD2DWORD(FaultPhaA_Curr);
            double FaultPhaA_Curr_Val = (double)(FaultPhaA_Curr * 1.0) / 1000;
            sTmp = pha + "相故障时电流: " + FaultPhaA_Curr_Val.ToString("000.000") + " A";
            textBox1.Text += sTmp + "\r\n";


            //pha 相故障前电流
            ulong BeforeFaultPha_Curr = (ulong)(Original[site + 9] << 16 | Original[site + 8] << 8 | Original[site + 7]);
            BeforeFaultPha_Curr = BCD2DWORD(BeforeFaultPha_Curr);
            double BeforeFaultPha_Curr_Val = (double)(BeforeFaultPha_Curr * 1.0) / 1000;
            sTmp = pha + "相故障前电流: " + BeforeFaultPha_Curr_Val.ToString("000.000") + " A";
            textBox1.Text += sTmp + "\r\n";


        }

        private void RecReadGzFdInfo()  //c = 0x81 应答 故障和复电信息
        {
            this.txt_CtrlItem.Text = "LTU应答故障和复电信息";
            if (MsgDI[3] == 0xFD)
            {
                //从站回复 复电信息
                ///复电发生的时间
                ///年 月 日 时 分 秒
                byte YY = 0; //年
                byte MM = 0;
                byte DD = 0;
                byte hh = 0;
                byte mm = 0;
                byte ss = 0;

                YY = BCD2BYTE((byte)(inputdata_hex[19]));
                MM = BCD2BYTE((byte)(inputdata_hex[18]));
                DD = BCD2BYTE((byte)(inputdata_hex[17]));
                hh = BCD2BYTE((byte)(inputdata_hex[16]));
                mm = BCD2BYTE((byte)(inputdata_hex[15]));
                ss = BCD2BYTE((byte)(inputdata_hex[14]));

                string sTmp = "复电的时间：" + "20" + YY.ToString() + "年" + MM.ToString() + "月" + DD.ToString() + "日" + hh.ToString() + "时" + mm.ToString() + "分" + ss.ToString() + "秒";
                textBox1.Text +=(sTmp);
            }
            if (MsgDI[3] == 0xFE)   //从站回复 复电和故障信息
            {
                //A 相故障标志
                int GzFlag_A = inputdata_hex[15] << 8 | inputdata_hex[14];
                sTmp = "A 相故障标志 : " + GzFlag_A.ToString("X4") + "  故障类型： ";
                JudgeGzFlag(GzFlag_A, sTmp);

                //B 相故障标志
                int GzFlag_B = inputdata_hex[17] << 8 | inputdata_hex[16];
                sTmp = "B 相故障标志 : " + GzFlag_B.ToString("X4") + "  故障类型： ";
                JudgeGzFlag(GzFlag_B, sTmp);

                //C 相故障标志
                int GzFlag_C = inputdata_hex[19] << 8 | inputdata_hex[18];
                sTmp = "C 相故障标志 : " + GzFlag_C.ToString("X4") + "  故障类型： ";
                JudgeGzFlag(GzFlag_C, sTmp);

                // A 相 
                ChangeValFormat(inputdata_hex, 20, "A");

                // B 相 
                ChangeValFormat(inputdata_hex, 30, "B");

                // C 相 
                ChangeValFormat(inputdata_hex, 40, "C");

                ///剩余次数
                byte ResidueDegree = 0;
                ResidueDegree = BCD2BYTE(inputdata_hex[inputdata_length - 9]);
                sTmp = "告警和故障剩余次数： " + ResidueDegree.ToString() + " 次";
                textBox1.Text += sTmp + "\r\n";

                ///故障发生的时间
                ///年 月 日 时 分 秒
                byte YY = 0; //年
                byte MM = 0;
                byte DD = 0;
                byte hh = 0;
                byte mm = 0;
                byte ss = 0;

                YY = BCD2BYTE((byte)(inputdata_hex[inputdata_length - 3]));
                MM = BCD2BYTE((byte)(inputdata_hex[inputdata_length - 4]));
                DD = BCD2BYTE((byte)(inputdata_hex[inputdata_length - 5]));
                hh = BCD2BYTE((byte)(inputdata_hex[inputdata_length - 6]));
                mm = BCD2BYTE((byte)(inputdata_hex[inputdata_length - 7]));
                ss = BCD2BYTE((byte)(inputdata_hex[inputdata_length - 8]));

                sTmp = "故障时间：" + "20" + YY.ToString() + "年" + MM.ToString() + "月" + DD.ToString() + "日" + hh.ToString() + "时" + mm.ToString() + "分" + ss.ToString() + "秒";
                textBox1.Text += sTmp + "\r\n";
            }
        }

        private void DoReadDdState() /// C = 0x02  读取从机的掉电状态
        {
            this.txt_CtrlItem.Text = "读掉电状态";
            textBox1.Text +=("读取从机的掉电状态") + "\r\n";
        }

        private void RecReadDdState()   /// c = 0x82 读掉电状态应答帧
        {
            this.txt_CtrlItem.Text = "LTU回复掉电状态";
            if (inputdata_hex[9] == 0x01)
            {
                textBox1.Text +=("装置无掉电");
            }
            else if (inputdata_hex[9] == 0x07)
            {
                ///故障发生的时间
                ///年 月 日 时 分 秒
                byte YY = 0; //年
                byte MM = 0;
                byte DD = 0;
                byte hh = 0;
                byte mm = 0;
                byte ss = 0;

                YY = BCD2BYTE((byte)(inputdata_hex[15]));
                MM = BCD2BYTE((byte)(inputdata_hex[14]));
                DD = BCD2BYTE((byte)(inputdata_hex[13]));
                hh = BCD2BYTE((byte)(inputdata_hex[12]));
                mm = BCD2BYTE((byte)(inputdata_hex[11]));
                ss = BCD2BYTE((byte)(inputdata_hex[10]));

                string sTmp = "下发的时间：" + "20" + YY.ToString() + "年" + MM.ToString() + "月" + DD.ToString() + "日" + hh.ToString() + "时" + mm.ToString() + "分" + ss.ToString() + "秒";
                textBox1.Text +=(sTmp);
            }
            else
            {
                textBox1.Text +=("字段未启用");
            }

        }

        private void DoFaultAck()    /// C  = 0x03 终端确认帧
        {
            this.txt_CtrlItem.Text = "终端确认帧";
            textBox1.Text += " 确保终端已经收到故障和复电信息，终端不再查询复电信息;故障和告警存储数组相应减一 ";
        }

        private void DoPassThrough()
        {
            this.txt_CtrlItem.Text = "LTU应答透传数据";
            textBox1.Text += "LTU应答透传数据" + "\r\n";

            string sTemp = " ";
            for (int i = 0; i < inputdata_hex[9] - 5; i++)
            {
                textBox1.Text += inputdata_hex[15 + i].ToString("X2") + " ";
            }
            textBox1.Text += "\r\n";
        }

        private void RecFaultAck()    /// C  = 0x83 应答终端确认帧
        {
            this.txt_CtrlItem.Text = "终端应答终端确认帧";
            textBox1.Text += "终端应答终端确认帧" + "\r\n";
        }

        private void RecErrAnswerReadGzFdInfo()/// 0xD9 读故障和复电信息异常应答帧
        {
            this.txt_CtrlItem.Text = "终端应答终端确认帧";
            textBox1.Text += " 读故障和复电信息 终端应答终端 数据异常帧 ";
        }

        private void DoReadSetClk() ///C   =0x08  对时
        {
            textBox1.Text += " 强制从站与主站时间同步，不要求应答 " + "\r\n";
            ///下发的时间
            ///年 月 日 时 分 秒
            byte YY = 0; //年
            byte MM = 0;
            byte DD = 0;
            byte hh = 0;
            byte mm = 0;
            byte ss = 0;

            YY = BCD2BYTE((byte)(inputdata_hex[15]));
            MM = BCD2BYTE((byte)(inputdata_hex[14]));
            DD = BCD2BYTE((byte)(inputdata_hex[13]));
            hh = BCD2BYTE((byte)(inputdata_hex[12]));
            mm = BCD2BYTE((byte)(inputdata_hex[11]));
            ss = BCD2BYTE((byte)(inputdata_hex[10]));

            string sTmp;
            sTmp = "下发的时间：" + "20" + YY.ToString() + "年" + MM.ToString() + "月" + DD.ToString() + "日" + hh.ToString() + "时" + mm.ToString() + "分" + ss.ToString() + "秒";

            textBox1.Text += sTmp + "\r\n";

        }


        private void RecYdDdSendAutoAck() ///0x79 掉电主动上报 应答主站回复帧
        {
            this.txt_CtrlItem.Text = "掉电主动上报";
            textBox1.Text += "掉电主动上报 应答主站回复帧" + "\r\n";
            ///掉电的时间
            ///年 月 日 时 分 秒
            byte YY = 0; //年
            byte MM = 0;
            byte DD = 0;
            byte hh = 0;
            byte mm = 0;
            byte ss = 0;

            YY = BCD2BYTE((byte)(inputdata_hex[16]));
            MM = BCD2BYTE((byte)(inputdata_hex[15]));
            DD = BCD2BYTE((byte)(inputdata_hex[14]));
            hh = BCD2BYTE((byte)(inputdata_hex[13]));
            mm = BCD2BYTE((byte)(inputdata_hex[12]));
            ss = BCD2BYTE((byte)(inputdata_hex[11]));

            string sTmp;
            sTmp = "掉电的时间：" + "20" + YY.ToString() + "年" + MM.ToString() + "月" + DD.ToString() + "日" + hh.ToString() + "时" + mm.ToString() + "分" + ss.ToString() + "秒";

            textBox1.Text += sTmp + "\r\n";
        }

        private void RecDdSendAutoAck() ///0x89 掉电主动上报
        {
            this.txt_CtrlItem.Text = "掉电主动上报";
            ///掉电的时间
            ///年 月 日 时 分 秒
            byte YY; //年
            byte MM;
            byte DD;
            byte hh;
            byte mm;
            byte ss;

            YY = BCD2BYTE((byte)(inputdata_hex[16]));
            MM = BCD2BYTE((byte)(inputdata_hex[15]));
            DD = BCD2BYTE((byte)(inputdata_hex[14]));
            hh = BCD2BYTE((byte)(inputdata_hex[13]));
            mm = BCD2BYTE((byte)(inputdata_hex[12]));
            ss = BCD2BYTE((byte)(inputdata_hex[11]));

            string sTmp;
            sTmp = "掉电的时间：" + "20" + YY.ToString() + "年" + MM.ToString() + "月" + DD.ToString() + "日" + hh.ToString() + "时" + mm.ToString() + "分" + ss.ToString() + "秒";

            textBox1.Text += sTmp + "\r\n";
        }

        private void DoDdSendAutoAck() ///0x09://掉电主动上报确认帧处理
        {
            textBox1.Text += " 掉电主动上报确认帧 " + "\r\n";
            ///掉电的时间
            ///年 月 日 时 分 秒
            byte YY = 0; //年
            byte MM = 0;
            byte DD = 0;
            byte hh = 0;
            byte mm = 0;
            byte ss = 0;

            YY = BCD2BYTE((byte)(inputdata_hex[16]));
            MM = BCD2BYTE((byte)(inputdata_hex[15]));
            DD = BCD2BYTE((byte)(inputdata_hex[14]));
            hh = BCD2BYTE((byte)(inputdata_hex[13]));
            mm = BCD2BYTE((byte)(inputdata_hex[12]));
            ss = BCD2BYTE((byte)(inputdata_hex[11]));

            string sTmp;
            sTmp = "掉电的时间：" + "20" + YY.ToString() + "年" + MM.ToString() + "月" + DD.ToString() + "日" + hh.ToString() + "时" + mm.ToString() + "分" + ss.ToString() + "秒";
            textBox1.Text += sTmp + "\r\n";

        }

        private void DoDataReadDeal() ///0x11 读数据
        {
            this.txt_CtrlItem.Text = "主站请求读数据";

            textBox1.Text += "读取数据 " + "\r\n";
            ///根据不同的DI有不同的显示 
            switch (MsgDI[0])
            {
                case 0x00:  ///电能量数据
                    if ((MsgDI[2] == 0x00) && (MsgDI[3] == 0x00))
                    {
                        switch (MsgDI[1])
                        {
                            case 0x01:
                                textBox1.Text += "(当前)正向有功总电能 " + "\r\n";
                                break;

                            case 0x02:
                                textBox1.Text += "(当前)反向有功总电能 " + "\r\n";
                                break;

                            case 0x03:
                                textBox1.Text += "(当前)组合无功1总电能 " + "\r\n";
                                break;

                            case 0x04:
                                textBox1.Text += "(当前)组合无功2总电能 " + "\r\n";
                                break;

                            case 0x05:
                                textBox1.Text += "(当前)第一象限无功总电能 " + "\r\n";
                                break;

                            case 0x06:
                                textBox1.Text += "(当前)第二象限无功总电能 " + "\r\n";
                                break;

                            case 0x07:
                                textBox1.Text += "(当前)第三象限无功总电能 " + "\r\n";
                                break;

                            case 0x08:
                                textBox1.Text += "(当前)第四象限无功总电能 " + "\r\n";
                                break;

                            //A 相
                            case 0x15:
                                textBox1.Text +=("(当前)A 相正向有功电能");
                                break;
                            case 0x16:
                                textBox1.Text +=("(当前)A 相反向有功电能");
                                break;
                            case 0x17:
                                textBox1.Text +=("(当前)A 相组合无功1电能");
                                break;
                            case 0x18:
                                textBox1.Text +=("(当前)A 相组合无功2电能");
                                break;
                            case 0x19:
                                textBox1.Text +=("(当前)A 相第一象限无功电能");
                                break;
                            case 0x1A:
                                textBox1.Text +=("(当前)A 相第二象限无功电能");
                                break;
                            case 0x1B:
                                textBox1.Text +=("(当前)A 相第三象限无功电能");
                                break;
                            case 0x1C:
                                textBox1.Text +=("(当前)A 相第四象限无功电能");
                                break;

                            //B 相
                            case 0x29:
                                textBox1.Text +=("(当前)B 相正向有功电能");
                                break;
                            case 0x2A:
                                textBox1.Text +=("(当前)B 相反向有功电能");
                                break;
                            case 0x2B:
                                textBox1.Text +=("(当前)B 相组合无功1电能");
                                break;
                            case 0x2C:
                                textBox1.Text +=("(当前)B 相组合无功2电能");
                                break;
                            case 0x2D:
                                textBox1.Text +=("(当前)B 相第一象限无功电能");
                                break;
                            case 0x2E:
                                textBox1.Text +=("(当前)B 相第二象限无功电能");
                                break;
                            case 0x2F:
                                textBox1.Text +=("(当前)B 相第三象限无功电能");
                                break;
                            case 0x30:
                                textBox1.Text +=("(当前)B 相第四象限无功电能");
                                break;

                            //C 相
                            case 0x3D:
                                textBox1.Text +=("(当前)C 相正向有功电能");
                                break;
                            case 0x3E:
                                textBox1.Text +=("(当前)C 相反向有功电能");
                                break;
                            case 0x3F:
                                textBox1.Text +=("(当前)C 相组合无功1电能");
                                break;
                            case 0x40:
                                textBox1.Text +=("(当前)C 相组合无功2电能");
                                break;
                            case 0x41:
                                textBox1.Text +=("(当前)C 相第一象限无功电能");
                                break;
                            case 0x42:
                                textBox1.Text +=("(当前)C 相第二象限无功电能");
                                break;
                            case 0x43:
                                textBox1.Text +=("(当前)C 相第三象限无功电能");
                                break;
                            case 0x44:
                                textBox1.Text +=("(当前)C 相第四象限无功电能");
                                break;

                            default:
                                textBox1.Text +=(" 无此数据项 ");
                                break;
                        }
                    }
                    break;

                case 0x02:  ///变量数据
                    switch (MsgDI[1])
                    {
                        case 0x01:
                            switch (MsgDI[2])
                            {
                                case 0x01:
                                    textBox1.Text +=("A 相电压 ");
                                    break;
                                case 0x02:
                                    textBox1.Text +=("B 相电压 ");
                                    break;
                                case 0x03:
                                    textBox1.Text +=("C 相电压 ");
                                    break;
                                case 0xFF:
                                    textBox1.Text +=(" 电压数据块 ");
                                    break;
                            }
                            break;
                        case 0x02:
                            switch (MsgDI[2])
                            {
                                case 0x01:
                                    textBox1.Text +=("A 相电流 ");
                                    break;
                                case 0x02:
                                    textBox1.Text +=("B 相电流 ");
                                    break;
                                case 0x03:
                                    textBox1.Text +=("C 相电流 ");
                                    break;
                                case 0xFF:
                                    textBox1.Text +=(" 电流数据块 ");
                                    break;
                            }
                            break;
                        case 0x03:
                            switch (MsgDI[2])
                            {
                                case 0x00:
                                    textBox1.Text +=("瞬时总有功功率");
                                    break;
                                case 0x01:
                                    textBox1.Text +=("瞬时A相有功功率 ");
                                    break;
                                case 0x02:
                                    textBox1.Text +=("瞬时B相有功功率 ");
                                    break;
                                case 0x03:
                                    textBox1.Text +=("瞬时C相有功功率 ");
                                    break;
                                case 0xFF:
                                    textBox1.Text +=(" 瞬时有功功率数据块 ");
                                    break;
                            }
                            break;
                        case 0x04:
                            switch (MsgDI[2])
                            {
                                case 0x00:
                                    textBox1.Text +=("瞬时总无功功率");
                                    break;
                                case 0x01:
                                    textBox1.Text +=("瞬时A相无功功率 ");
                                    break;
                                case 0x02:
                                    textBox1.Text +=("瞬时B相无功功率 ");
                                    break;
                                case 0x03:
                                    textBox1.Text +=("瞬时C相无功功率 ");
                                    break;
                                case 0xFF:
                                    textBox1.Text +=(" 瞬时无功功率数据块 ");
                                    break;
                            }
                            break;
                        case 0x05:
                            switch (MsgDI[2])
                            {
                                case 0x00:
                                    textBox1.Text +=("瞬时总视在功率");
                                    break;
                                case 0x01:
                                    textBox1.Text +=("瞬时A相视在功率 ");
                                    break;
                                case 0x02:
                                    textBox1.Text +=("瞬时B相视在功率 ");
                                    break;
                                case 0x03:
                                    textBox1.Text +=("瞬时C相视在功率 ");
                                    break;
                                case 0xFF:
                                    textBox1.Text +=(" 瞬时视在功率数据块 ");
                                    break;
                            }
                            break;
                        case 0x06:
                            switch (MsgDI[2])
                            {
                                case 0x00:
                                    textBox1.Text +=("总功率因数");
                                    break;
                                case 0x01:
                                    textBox1.Text +=("A 相功率因数 ");
                                    break;
                                case 0x02:
                                    textBox1.Text +=("B 相功率因数 ");
                                    break;
                                case 0x03:
                                    textBox1.Text +=("C 相功率因数 ");
                                    break;
                                case 0xFF:
                                    textBox1.Text +=(" 功率因数数据块 ");
                                    break;
                            }
                            break;
                        case 0x07:
                            switch (MsgDI[2])
                            {
                                case 0x01:
                                    textBox1.Text +=("A 相相角 ");
                                    break;
                                case 0x02:
                                    textBox1.Text +=("B 相相角 ");
                                    break;
                                case 0x03:
                                    textBox1.Text +=("C 相相角 ");
                                    break;
                                case 0xFF:
                                    textBox1.Text +=(" 相角数据块 ");
                                    break;
                            }
                            break;

                        case 0x80:
                            if ((MsgDI[2] == 0) && (MsgDI[3] == 0x01))
                            {
                                textBox1.Text +=(" 零线电流 ");
                            }
                            else if ((MsgDI[2] == 0) && (MsgDI[3] == 0x01))
                            {
                                textBox1.Text +=(" 电网频率 ");
                            }
                            break;

                        case 0x81:
                            if ((MsgDI[2] == 0x00) && (MsgDI[3] == 0x00))
                            {
                                textBox1.Text +=(" 板载温度 ");
                            }
                            break;

                    }
                    break;

                case 0x03:  ///事件记录
                    switch (MsgDI[1])
                    {
                        case 0x34:
                            switch (MsgDI[2])
                            {
                                case 0x00:  //硬遥信变位次数
                                    if (MsgDI[3] == 0x00)
                                    {
                                        textBox1.Text +=("硬遥信1变位次数");
                                    }
                                    if (MsgDI[3] == 0x01)
                                    {
                                        textBox1.Text +=("硬遥信2变位次数");
                                    }
                                    break;

                                case 0x01:
                                    switch (MsgDI[3])
                                    {
                                        case 0x01:
                                            textBox1.Text +=("（上1次）硬遥信1变位后状态，发生时刻");
                                            break;
                                        case 0x02:
                                            textBox1.Text +=("（上2次）硬遥信1变位后状态，发生时刻");
                                            break;
                                        case 0x03:
                                            textBox1.Text +=("（上3次）硬遥信1变位后状态，发生时刻");
                                            break;
                                        case 0x04:
                                            textBox1.Text +=("（上4次）硬遥信1变位后状态，发生时刻");
                                            break;
                                        case 0x05:
                                            textBox1.Text +=("（上5次）硬遥信1变位后状态，发生时刻");
                                            break;
                                        case 0x06:
                                            textBox1.Text +=("（上6次）硬遥信1变位后状态，发生时刻");
                                            break;
                                        case 0x07:
                                            textBox1.Text +=("（上7次）硬遥信1变位后状态，发生时刻");
                                            break;
                                        case 0x08:
                                            textBox1.Text +=("（上8次）硬遥信1变位后状态，发生时刻");
                                            break;
                                        case 0x09:
                                            textBox1.Text +=("（上9次）硬遥信1变位后状态，发生时刻");
                                            break;
                                        case 0x0A:
                                            textBox1.Text +=("（上10次）硬遥信1变位后状态，发生时刻");
                                            break;
                                    }
                                    break;

                                case 0x02:
                                    switch (MsgDI[3])
                                    {
                                        case 0x01:
                                            textBox1.Text +=("（上1次）硬遥信2变位后状态，发生时刻");
                                            break;
                                        case 0x02:
                                            textBox1.Text +=("（上2次）硬遥信2变位后状态，发生时刻");
                                            break;
                                        case 0x03:
                                            textBox1.Text +=("（上3次）硬遥信2变位后状态，发生时刻");
                                            break;
                                        case 0x04:
                                            textBox1.Text +=("（上4次）硬遥信2变位后状态，发生时刻");
                                            break;
                                        case 0x05:
                                            textBox1.Text +=("（上5次）硬遥信2变位后状态，发生时刻");
                                            break;
                                        case 0x06:
                                            textBox1.Text +=("（上6次）硬遥信2变位后状态，发生时刻");
                                            break;
                                        case 0x07:
                                            textBox1.Text +=("（上7次）硬遥信2变位后状态，发生时刻");
                                            break;
                                        case 0x08:
                                            textBox1.Text +=("（上8次）硬遥信2变位后状态，发生时刻");
                                            break;
                                        case 0x09:
                                            textBox1.Text +=("（上9次）硬遥信2变位后状态，发生时刻");
                                            break;
                                        case 0x0A:
                                            textBox1.Text +=("（上10次）硬遥信2变位后状态，发生时刻");
                                            break;
                                    }
                                    break;
                            }

                            break;

                        case 0x35:
                            string sTmp = "上" + MsgDI[3].ToString() + "次" + "topo识别结果";
                            textBox1.Text +=(sTmp);
                            break;

                        default:
                            break;

                    }
                    break;

                case 0x04:
                    switch (MsgDI[1])
                    {
                        case 0x00:
                            switch (MsgDI[2])
                            {
                                case 0x01:
                                    if (MsgDI[3] == 0x01)
                                    {
                                        textBox1.Text +=("主站抄读：年月日星期");
                                    }
                                    if (MsgDI[3] == 0x02)
                                    {
                                        textBox1.Text +=("主站抄读：时分秒");
                                    }
                                    break;

                                case 0x02:
                                    textBox1.Text +=("主站抄读:当前表类型");
                                    break;

                                case 0x04:
                                    if (MsgDI[3] == 0x01)
                                    {
                                        textBox1.Text +=("主站抄读： 通信地址");
                                    }
                                    if (MsgDI[3] == 0x09)
                                    {
                                        textBox1.Text +=("主站抄读： 电表有功常数");
                                    }
                                    break;

                                case 0x05:
                                    switch (MsgDI[3])
                                    {
                                        case 0x01:
                                            textBox1.Text +=("电表运行状态字 1 ");
                                            break;
                                        case 0x08:
                                            textBox1.Text +=("主站查询：故障和复电信息 ");
                                            break;
                                        case 0x09:
                                            textBox1.Text +=("有事件发生，主动上送 ");
                                            break;

                                        case 0xFD:
                                            textBox1.Text +=("读取复电信息：日期 ");
                                            break;

                                        case 0xFE:
                                            textBox1.Text +=("故障具体事件信息 ");
                                            break;

                                    }
                                    break;

                                case 0x15:
                                    textBox1.Text +=("拉 Event 引脚，从站主动上送 信息！ ");
                                    break;

                            }
                            break;

                        case 0x09:
                            textBox1.Text +=("主站设置阈值");
                            break;

                        case 0x10:
                            if (MsgDI[3] == 0x00)
                            {
                                textBox1.Text +=("主站设置 硬遥信1防抖参数");
                            }
                            if (MsgDI[3] == 0x01)
                            {
                                textBox1.Text +=("主站设置 硬遥信2防抖参数");
                            }
                            break;
                    }
                    break;

                case 0x05:  //冻结数据
                    if (MsgDI[1] == 0x04)
                    {
                        switch (MsgDI[2])
                        {
                            case 0x00:
                                string sTmp = "上" + MsgDI[3].ToString() + "次" + "整点冻结时间";
                                textBox1.Text += sTmp + "\r\n";
                                break;

                            case 0x01:
                                sTmp = "上" + MsgDI[3].ToString() + "次" + "整点冻结正向有功总电能";
                                textBox1.Text += (sTmp);
                                break;

                            case 0x02:
                                sTmp = "上" + MsgDI[3].ToString() + "次" + "整点冻结反向有功总电能";
                                textBox1.Text += (sTmp);
                                break;

                            case 0xFF:
                                sTmp = "上" + MsgDI[3].ToString() + "次" + "整点冻结数据块";
                                textBox1.Text += (sTmp);
                                break;
                        }
                    }
                    else if ((MsgDI[1] == 0x08) || (MsgDI[2] == 0x00))
                    {
                        switch (MsgDI[3])
                        {
                            case 0x01:
                                string sTmp = "15分钟冻结 ";
                                textBox1.Text += sTmp + "\r\n";
                                break;
                        }
                    }
                    break;

                case 0x07:
                    if ((MsgDI[1] == 0x00) && (MsgDI[2] == 0x00) && (MsgDI[3] == 0x01))
                    {
                        if ((inputdata_hex[14] == 0x02) && (inputdata_hex[15] == 0x05))
                        {
                            textBox1.Text +=("主站查询：电压 电流 功率");
                        }
                        if ((inputdata_hex[14] == 0x10) && (inputdata_hex[15] == 0x05))
                        {
                            textBox1.Text +=("主站查询：全数据");
                        }
                    }
                    break;

            }
        }

        private void FormatDataOfElectricalEnergy4Byte(byte[] Original, int site, string str, string unit, int gain) //4 位 电能量数据转换
        {
            //bool SignBit = false;
            string SignBit = " ";
            if ((Original[site + 3] & 0x80) == 0x80)
            {
                SignBit = "-";
            }

            if (gain != 0x01)
            {
                Original[site + 3] &= 0x7F;
            }

            ulong Val = ((ulong)(Original[site] | Original[site + 1] << 8 | Original[site + 2] << 16 | Original[site + 3] << 24));
            Val = BCD2DWORD(Val);

            float ValNum = 0;

            if (gain == 100 || gain == 10000 || gain == 1000000)
            {
                ValNum = (float)Val / gain;
            }


            switch (gain)
            {
                case 0x01:
                    sTmp = str + SignBit + Val.ToString("00000000") + unit;

                    break;

                case 111:   ///冻结特殊的电量倍数
                    ValNum = (float)((float)Val / 100.0);
                    sTmp = str + SignBit + ValNum.ToString("000000.00") + unit;
                    break;

                case 100:
                    sTmp = str + SignBit + ValNum.ToString("000000.00") + unit;
                    break;

                case 10000:
                    sTmp = str + SignBit + ValNum.ToString("0000.0000") + unit;
                    break;


                case 200000:
                    /*                    Val &= 0x7fffffff;*//**/
                    ValNum = (float)(Val / 10000.0 * 20.0);
                    sTmp = str + SignBit + ValNum.ToString("0000.0000") + unit;
                    break;

                case 1000000:
                    sTmp = str + SignBit + ValNum.ToString("00.000000") + unit;
                    break;

                case 20000000:
                    ////Val &= 0x7fffffff;
                    ValNum = (float)(Val / 1000000.0 * 20.0);
                    sTmp = str + SignBit + ValNum.ToString("00.000000") + unit;
                    break;
            }

            textBox1.Text += sTmp + "\r\n";
        }

        private void FormatDataOfElectricalEnergy3Byte(byte[] Original, int site, string str, string unit, int gain) //3 位 电能量数据转换
        {
            string SignBit = " ";

            float ValNum = 0;
            ulong Val = ((ulong)(Original[site] | Original[site + 1] << 8 | (Original[site + 2] & 0x7F) << 16));
            Val = BCD2DWORD(Val);

            if (gain != 10000 * 20)
            {
                ValNum = (float)Val / gain;
            }


            switch (gain)
            {
                case 1:
                    sTmp = str + " " + ValNum.ToString("000000") + unit;
                    break;

                case 1000:
                    sTmp = str + " " + ValNum.ToString("000.000") + unit;
                    break;

                case 10000:
                    sTmp = str + " " + ValNum.ToString("00.0000") + unit;
                    break;

                case 20000:   /// 电流
                    ValNum = (float)((float)(Val) * 20.0 / 1000.0);
                    sTmp = str + " " + ValNum.ToString("000.000") + unit;
                    break;


                case 100000:   /// 功率因数
                    //ValNum = (float)((float)(Val) * 20.0 / 1000.0);
                    if ((Original[site + 2] & 0x80) == 0x80)
                    {
                        SignBit = "-";
                    }
                    sTmp = str + SignBit + ValNum.ToString("0.00000") + unit;
                    break;

                case 200000:  ///功率
                    Val = ((ulong)(Original[site] | Original[site + 1] << 8 | Original[site + 2] << 16) & 0x7FFFFF);
                    Val = BCD2DWORD(Val);
                    ValNum = (float)((float)Val * 20.0 / 10000.0);
                    sTmp = str + " " + ValNum.ToString("00.0000") + unit;
                    break;

            }


            textBox1.Text += sTmp + "\r\n";
        }

        private void FormatData0fVariable2Byte(byte[] Original, int site, string str, string unit, int gain)
        {
            ushort Val = ((ushort)(Original[site] | Original[site + 1] << 8));
            Val = BCD2WORD(Val);
            float ValNum = (float)((float)Val / 1.0) / gain;

            switch (gain)
            {
                case 1:
                    sTmp = str + " " + ValNum.ToString("0000") + unit;
                    break;
                case 10:
                    sTmp = str + " " + ValNum.ToString("000.0") + unit;
                    break;

                case 100:
                    sTmp = str + " " + ValNum.ToString("00.00") + unit;
                    break;

                case 1000:
                    sTmp = str + " " + ValNum.ToString("0.000") + unit;
                    break;
            }

            textBox1.Text += sTmp + "\r\n";

        }

        private void FormatData2ByteBCD(byte[] Original, int site, string str, string unit, int gain)
        {
            ushort Val = ((ushort)(Original[site] | Original[site + 1] << 8));
            Val = WORD2BCD(Val);
            float ValNum = (float)((float)Val / 1.0) / gain;

            switch (gain)
            {
                case 1:
                    sTmp = str + " " + Val.ToString("X2") + unit;
                    break;
                case 10:
                    sTmp = str + " " + ValNum.ToString("000.0") + unit;
                    break;

                case 100:
                    sTmp = str + " " + ValNum.ToString("00.00") + unit;
                    break;

                case 1000:
                    sTmp = str + " " + ValNum.ToString("0.000") + unit;
                    break;
            }

            textBox1.Text += sTmp + "\r\n";

        }


        private void HardRemoteInfo(byte[] Original, int site, int count, int items)
        {
            sTmp = "上" + count.ToString() + "次" + "遥信" + items.ToString() + "变位后状态:";
            if (Original[site] == 0x00)
            {
                sTmp += " 关 ";
            }
            else if (Original[site] == 0x01)
            {
                sTmp += " 开 ";
            }

            ///发生的时间
            ///年 月 日 时 分 秒
            byte YY = 0; //年
            byte MM = 0;
            byte DD = 0;
            byte hh = 0;
            byte mm = 0;
            byte ss = 0;

            YY = BCD2BYTE((byte)(inputdata_hex[site + 6]));
            MM = BCD2BYTE((byte)(inputdata_hex[site + 5]));
            DD = BCD2BYTE((byte)(inputdata_hex[site + 4]));
            hh = BCD2BYTE((byte)(inputdata_hex[site + 3]));
            mm = BCD2BYTE((byte)(inputdata_hex[site + 2]));
            ss = BCD2BYTE((byte)(inputdata_hex[site + 1]));

            sTmp += "时间：" + "20" + YY.ToString() + "年" + MM.ToString() + "月" + DD.ToString() + "日" + hh.ToString() + "时" + mm.ToString() + "分" + ss.ToString() + "秒";
            textBox1.Text +=(sTmp);

        }
        private void RecReadDeal()  //0x91 LTU 回复读数据
        {
            this.txt_CtrlItem.Text = "设备回复读数据";
            ///根据不同的DI有不同的显示 
            switch (MsgDI[0])
            {
                case 0x00:  ///电能量数据
                    if ((MsgDI[2] == 0x00) && (MsgDI[3] == 0x00))
                    {
                        switch (MsgDI[1])
                        {
                            case 0x01:    //DI = 00010000
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)正向有功总电能  ", " kWh", 100);
                                break;

                            case 0x02:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)反向有功总电能 ", " kWh", 100);
                                break;

                            case 0x03:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)组合无功1总电能", " kvarh", 100);
                                break;

                            case 0x04:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)组合无功2总电能", " kvarh", 100);
                                break;

                            case 0x05:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)第一象限无功总电能", " kvarh", 100);
                                break;

                            case 0x06:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)第二象限无功总电能", " kvarh", 100);
                                break;

                            case 0x07:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)第三象限无功总电能", " kvarh", 100);
                                break;

                            case 0x08:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)第四象限无功总电能", " kvarh", 100);
                                break;

                            //A 相
                            case 0x15:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)A 相正向有功电能", " kWh", 100);
                                break;
                            case 0x16:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)A 相反向有功电能", " kWh", 100);
                                break;
                            case 0x17:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)A 相组合无功1电能", " kvarh", 100);
                                break;
                            case 0x18:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)A 相组合无功2电能", " kvarh", 100);
                                break;
                            case 0x19:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)A 相第一象限无功电能", " kvarh", 100);
                                break;
                            case 0x1A:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)A 相第二象限无功电能", " kvarh", 100);
                                break;
                            case 0x1B:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)A 相第三象限无功电能", " kvarh", 100);
                                break;
                            case 0x1C:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)A 相第四象限无功电能", " kvarh", 100);
                                break;

                            //B 相
                            case 0x29:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)B 相正向有功电能", " kWh", 100);
                                break;
                            case 0x2A:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)B 相反向有功电能", " kWh", 100);
                                break;
                            case 0x2B:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)B 相组合无功1电能", " kvarh", 100);
                                break;
                            case 0x2C:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)B 相组合无功2电能", " kvarh", 100);
                                break;
                            case 0x2D:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)B 相第一象限无功电能", " kvarh", 100);
                                break;
                            case 0x2E:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)B 相第二象限无功电能", " kvarh", 100);
                                break;
                            case 0x2F:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)B 相第三象限无功电能", " kvarh", 100);
                                break;
                            case 0x30:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)B 相第四象限无功电能", " kvarh", 100);
                                break;

                            //C 相
                            case 0x3D:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)C 相正向有功电能", " kWh", 100);
                                break;
                            case 0x3E:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)C 相反向有功电能", " kWh", 100);
                                break;
                            case 0x3F:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)C 相组合无功1电能", " kvarh", 100);
                                break;
                            case 0x40:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)C 相组合无功2电能", " kvarh", 100);
                                break;
                            case 0x41:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)C 相第一象限无功电能", " kvarh", 100);
                                break;
                            case 0x42:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)C 相第二象限无功电能", " kvarh", 100);
                                break;
                            case 0x43:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)C 相第三象限无功电能", " kvarh", 100);
                                break;
                            case 0x44:
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, "(当前)C 相第四象限无功电能", " kvarh", 100);
                                break;

                            default:
                                textBox1.Text +=(" 无此数据项 ") + "\r\n";
                                break;
                        }
                    }
                    break;

                case 0x02:  ///变量数据
                    switch (MsgDI[1])
                    {
                        case 0x01:
                            switch (MsgDI[2])
                            {
                                case 0x01:
                                    FormatData0fVariable2Byte(inputdata_hex, 14, "A 相电压 ", " V", 10);
                                    break;
                                case 0x02:
                                    FormatData0fVariable2Byte(inputdata_hex, 14, "B 相电压 ", " V", 10);
                                    break;
                                case 0x03:
                                    FormatData0fVariable2Byte(inputdata_hex, 14, "C 相电压 ", " V", 10);
                                    break;
                                case 0xFF:
                                    textBox1.Text +=(" 电压数据块 ");
                                    FormatData0fVariable2Byte(inputdata_hex, 14, "A 相电压 ", " V", 10);
                                    FormatData0fVariable2Byte(inputdata_hex, 16, "B 相电压 ", " V", 10);
                                    FormatData0fVariable2Byte(inputdata_hex, 18, "C 相电压 ", " V", 10);
                                    break;
                            }
                            break;
                        case 0x02:
                            switch (MsgDI[2])
                            {
                                case 0x01:
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 14, "A 相电流 ", " A", 1000 * 20);
                                    break;
                                case 0x02:
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 14, "B 相电流 ", " A", 1000 * 20);
                                    break;
                                case 0x03:
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 14, "C 相电流 ", " A", 1000 * 20);
                                    break;
                                case 0xFF:
                                    textBox1.Text +=("电流数据块") + "\r\n";
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 14, "A 相电流 ", " A", 1000 * 20);
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 17, "B 相电流 ", " A", 1000 * 20);
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 20, "C 相电流 ", " A", 1000 * 20);
                                    break;
                            }
                            break;
                        case 0x03:
                            switch (MsgDI[2])
                            {
                                case 0x00:
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 14, "瞬时总有功功率  ", " kW", 10000 * 20);
                                    break;
                                case 0x01:
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 14, "瞬时A相有功功率 ", " kW", 10000 * 20);
                                    break;
                                case 0x02:
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 14, "瞬时B相有功功率 ", " kW", 10000 * 20);
                                    break;
                                case 0x03:
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 14, "瞬时C相有功功率 ", " kW", 10000 * 20);
                                    break;
                                case 0xFF:
                                    textBox1.Text +=(" 瞬时有功功率数据块 ") + "\r\n";
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 14, "瞬时总有功功率  ", " kW", 10000 * 20);
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 17, "瞬时A相有功功率 ", " kW", 10000 * 20);
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 20, "瞬时B相有功功率 ", " kW", 10000 * 20);
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 23, "瞬时C相有功功率 ", " kW", 10000 * 20);
                                    break;
                            }
                            break;
                        case 0x04:
                            switch (MsgDI[2])
                            {
                                case 0x00:
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 14, "瞬时总无功功率", " kW", 10000 * 20);
                                    break;
                                case 0x01:
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 14, "瞬时A相无功功率 ", " kW", 10000 * 20);
                                    break;
                                case 0x02:
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 14, "瞬时B相无功功率 ", " kW", 10000 * 20);
                                    break;
                                case 0x03:
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 14, "瞬时C相无功功率 ", " kW", 10000 * 20);
                                    break;
                                case 0xFF:
                                    textBox1.Text +=(" 瞬时无功功率数据块 ") + "\r\n";
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 14, "瞬时总无功功率", " kW", 10000 * 20);
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 17, "瞬时A相无功功率 ", " kW", 10000 * 20);
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 20, "瞬时B相无功功率 ", " kW", 10000 * 20);
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 23, "瞬时C相无功功率 ", " kW", 10000 * 20);
                                    break;
                            }
                            break;
                        case 0x05:
                            switch (MsgDI[2])
                            {
                                case 0x00:
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 14, "瞬时总视在功率", " kW", 10000 * 20);
                                    break;
                                case 0x01:
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 14, "瞬时A相视在功率 ", " kW", 10000 * 20);
                                    break;
                                case 0x02:
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 14, "瞬时B相视在功率 ", " kW", 10000 * 20);
                                    break;
                                case 0x03:
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 14, "瞬时C相视在功率 ", " kW", 10000 * 20);
                                    break;
                                case 0xFF:
                                    textBox1.Text +=(" 瞬时视在功率数据块 ");
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 14, "瞬时总视在功率", " kW", 10000 * 20);
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 17, "瞬时A相视在功率 ", " kW", 10000 * 20);
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 20, "瞬时B相视在功率 ", " kW", 10000 * 20);
                                    FormatDataOfElectricalEnergy3Byte(inputdata_hex, 23, "瞬时C相视在功率 ", " kW", 10000 * 20);
                                    break;
                            }
                            break;
                        case 0x06:
                            switch (MsgDI[2])
                            {
                                case 0x00:
                                    FormatData0fVariable2Byte(inputdata_hex, 14, "总功率因数 ", "  ", 1000);
                                    break;
                                case 0x01:
                                    FormatData0fVariable2Byte(inputdata_hex, 14, "A 相功率因数 ", "  ", 1000);
                                    break;
                                case 0x02:
                                    FormatData0fVariable2Byte(inputdata_hex, 14, "B 相功率因数 ", "  ", 1000);
                                    break;
                                case 0x03:
                                    FormatData0fVariable2Byte(inputdata_hex, 14, "C 相功率因数 ", "  ", 1000);
                                    break;
                                case 0xFF:
                                    textBox1.Text +=(" 功率因数数据块 ");
                                    FormatData0fVariable2Byte(inputdata_hex, 14, "总功率因数 ", "  ", 1000);
                                    FormatData0fVariable2Byte(inputdata_hex, 16, "A 相功率因数 ", "  ", 1000);
                                    FormatData0fVariable2Byte(inputdata_hex, 18, "B 相功率因数 ", "  ", 1000);
                                    FormatData0fVariable2Byte(inputdata_hex, 20, "C 相功率因数 ", "  ", 1000);
                                    break;
                            }
                            break;
                        case 0x07:
                            switch (MsgDI[2])
                            {
                                case 0x01:
                                    textBox1.Text +=(" ");
                                    FormatData0fVariable2Byte(inputdata_hex, 14, "A 相相角 ", " °", 10);
                                    break;
                                case 0x02:
                                    FormatData0fVariable2Byte(inputdata_hex, 16, "B 相相角 ", " °", 10);
                                    break;
                                case 0x03:
                                    FormatData0fVariable2Byte(inputdata_hex, 18, "C 相相角 ", " °", 10);
                                    break;
                                case 0xFF:
                                    textBox1.Text +=(" 相角数据块 ");
                                    FormatData0fVariable2Byte(inputdata_hex, 14, "A 相相角 ", " °", 10);
                                    FormatData0fVariable2Byte(inputdata_hex, 16, "B 相相角 ", " °", 10);
                                    FormatData0fVariable2Byte(inputdata_hex, 18, "C 相相角 ", " °", 10);
                                    break;
                            }
                            break;

                        case 0x80:
                            if ((MsgDI[2] == 0) && (MsgDI[3] == 0x01))
                            {
                                FormatDataOfElectricalEnergy3Byte(inputdata_hex, 14, "零线电流: ", " A", 1000);
                            }
                            else if ((MsgDI[2] == 0) && (MsgDI[3] == 0x01))
                            {
                                FormatData0fVariable2Byte(inputdata_hex, 14, " 电网频率 :", " Hz ", 100);
                            }
                            break;

                        case 0x81:
                            if ((MsgDI[2] == 0x00) && (MsgDI[3] == 0x00))
                            {
                                FormatData0fVariable2Byte(inputdata_hex, 14, " 板载温度 :", " ℃ ", 10);
                            }
                            break;
                    }
                    break;

                case 0x03:  ///事件记录

                    TopoResultInfo TopoPwmInfo = new TopoResultInfo();  ///topo 识别结果存放

                    if (MsgDI[1] == 0x34)
                    {
                        switch (MsgDI[2])
                        {
                            case 0x00:  //硬遥信变位次数
                                if (MsgDI[3] == 0x00)
                                {
                                    sTmp = "硬遥信1变位次数: " + inputdata_hex[14].ToString() + " 次";
                                    textBox1.Text +=(sTmp);
                                }
                                if (MsgDI[3] == 0x01)
                                {
                                    sTmp = "硬遥信2变位次数: " + inputdata_hex[14].ToString() + " 次";
                                    textBox1.Text +=(sTmp);
                                }
                                break;

                            case 0x01:
                                switch (MsgDI[3])
                                {
                                    case 0x01:
                                        HardRemoteInfo(inputdata_hex, 14, 1, 1);
                                        break;
                                    case 0x02:
                                        HardRemoteInfo(inputdata_hex, 14, 2, 1);
                                        break;
                                    case 0x03:
                                        HardRemoteInfo(inputdata_hex, 14, 3, 1);
                                        break;
                                    case 0x04:
                                        HardRemoteInfo(inputdata_hex, 14, 4, 1);
                                        break;
                                    case 0x05:
                                        HardRemoteInfo(inputdata_hex, 14, 5, 1);
                                        break;
                                    case 0x06:
                                        HardRemoteInfo(inputdata_hex, 14, 6, 1);
                                        break;
                                    case 0x07:
                                        HardRemoteInfo(inputdata_hex, 14, 7, 1);
                                        break;
                                    case 0x08:
                                        HardRemoteInfo(inputdata_hex, 14, 8, 1);
                                        break;
                                    case 0x09:
                                        HardRemoteInfo(inputdata_hex, 14, 9, 1);
                                        break;
                                    case 0x0A:
                                        HardRemoteInfo(inputdata_hex, 14, 10, 1);
                                        break;
                                }
                                break;

                            case 0x02:
                                switch (MsgDI[3])
                                {
                                    case 0x01:
                                        HardRemoteInfo(inputdata_hex, 14, 1, 2);
                                        break;
                                    case 0x02:
                                        HardRemoteInfo(inputdata_hex, 14, 2, 2);
                                        break;
                                    case 0x03:
                                        HardRemoteInfo(inputdata_hex, 14, 3, 2);
                                        break;
                                    case 0x04:
                                        HardRemoteInfo(inputdata_hex, 14, 4, 2);
                                        break;
                                    case 0x05:
                                        HardRemoteInfo(inputdata_hex, 14, 5, 2);
                                        break;
                                    case 0x06:
                                        HardRemoteInfo(inputdata_hex, 14, 6, 2);
                                        break;
                                    case 0x07:
                                        HardRemoteInfo(inputdata_hex, 14, 7, 2);
                                        break;
                                    case 0x08:
                                        HardRemoteInfo(inputdata_hex, 14, 8, 2);
                                        break;
                                    case 0x09:
                                        HardRemoteInfo(inputdata_hex, 14, 9, 2);
                                        break;
                                    case 0x0A:
                                        HardRemoteInfo(inputdata_hex, 14, 10, 2);
                                        break;
                                }
                                break;
                        }
                    }
                    else if (MsgDI[1] == 0x35)
                    {
                        sTmp = "Topo识别 结果";
                        textBox1.Text +=(sTmp);

                        TopoPwmInfo.curclk.wYear = ((ushort)(inputdata_hex[14] | (inputdata_hex[15] << 8)));
                        TopoPwmInfo.curclk.byMonth = (inputdata_hex[16]);
                        TopoPwmInfo.curclk.byDay = (inputdata_hex[17]);
                        TopoPwmInfo.curclk.byWeek = (inputdata_hex[18]);
                        TopoPwmInfo.curclk.byHour = (inputdata_hex[19]);
                        TopoPwmInfo.curclk.byMinute = (inputdata_hex[20]);
                        TopoPwmInfo.curclk.bySecond = (inputdata_hex[21]);
                        TopoPwmInfo.curclk.wMSecond = ((ushort)(inputdata_hex[22] | (inputdata_hex[23] << 8)));

                        TopoPwmInfo.pha = BCD2WORD((ushort)(inputdata_hex[24] | (inputdata_hex[25] << 8)));
                        TopoPwmInfo.pwm_index = BCD2WORD((ushort)(inputdata_hex[26] | (inputdata_hex[27] << 8)));
                        ///TopoPwmInfo.seq = BCD2WORD((ushort)(inputdata_hex[28] | (inputdata_hex[29] << 8)));
                        TopoPwmInfo.seq = (ushort)(inputdata_hex[28] | (inputdata_hex[29] << 8));

                        string tmpPha;

                        switch (TopoPwmInfo.pha)
                        {
                            case 0x01:
                                tmpPha = "A";
                                break;

                            case 0x02:
                                tmpPha = "B";
                                break;

                            case 0x03:
                                tmpPha = "C";
                                break;

                            default:
                                tmpPha = "异常";
                                break;

                        }

                        sTmp = "时间：" + TopoPwmInfo.curclk.wYear.ToString() + "-" + TopoPwmInfo.curclk.byMonth.ToString() + "-"
                            + TopoPwmInfo.curclk.byDay.ToString() + "-" + TopoPwmInfo.curclk.byHour.ToString() + "-"
                            + TopoPwmInfo.curclk.byMinute.ToString() + "-" + TopoPwmInfo.curclk.bySecond.ToString() + "  "
                            + "相别：" + tmpPha + "  "
                            + "序列 " + TopoPwmInfo.pwm_index.ToString("X2") + "  "
                            + "波形：" + TopoPwmInfo.seq.ToString("X2");

                        textBox1.Text +=(sTmp);


                    }
                    break;

                case 0x04:
                    switch (MsgDI[1])
                    {
                        case 0x00:
                            switch (MsgDI[2])
                            {
                                case 0x01:
                                    if (MsgDI[3] == 0x01)
                                    {
                                        //textBox1.Text +=("主站抄读：年月日星期");
                                        //从站回复时间信息
                                        ///年 月 日 时 分 秒
                                        byte YY = 0; //年
                                        byte MM = 0;
                                        byte DD = 0;
                                        byte WW = 0; //星期


                                        YY = BCD2BYTE((byte)(inputdata_hex[17]));
                                        MM = BCD2BYTE((byte)(inputdata_hex[16]));
                                        DD = BCD2BYTE((byte)(inputdata_hex[15]));
                                        WW = BCD2BYTE((byte)(inputdata_hex[14]));


                                        string sTmp = "从站回复时间：" + "20" + YY.ToString() + "年" + MM.ToString() + "月" + DD.ToString() + "日" + "星期" + WW.ToString();
                                        textBox1.Text +=(sTmp);
                                    }
                                    if (MsgDI[3] == 0x02)
                                    {
                                        byte hh = 0;
                                        byte mm = 0;
                                        byte ss = 0;

                                        hh = BCD2BYTE((byte)(inputdata_hex[16]));
                                        mm = BCD2BYTE((byte)(inputdata_hex[15]));
                                        ss = BCD2BYTE((byte)(inputdata_hex[14]));

                                        string sTmp = "从站回复时间：" + hh.ToString() + "时" + mm.ToString() + "分" + ss.ToString() + "秒";
                                        textBox1.Text +=(sTmp);
                                    }
                                    break;

                                case 0x02:  //DI = 04000207 
                                    sTmp = "从站回复 当前表类型： ";
                                    if (inputdata_hex[14] == 0x01)
                                    {
                                        sTmp += "主动采集型";
                                    }
                                    else if (inputdata_hex[14] == 0x00)
                                    {
                                        sTmp += "非主动采集型";
                                    }
                                    else
                                    {
                                        sTmp += "未知型";
                                    }

                                    textBox1.Text +=(sTmp);

                                    break;

                                case 0x04:
                                    if (MsgDI[3] == 0x01)
                                    {
                                        sTmp = "当前表地址：";
                                        ///表地址
                                        byte[] MeterID = new byte[6];
                                        for (int i = 0; i < 6; i++)
                                        {
                                            MeterID[5 - i] = inputdata_hex[i + 14];
                                        }
                                        sTmp += bytesToHexString(MeterID, 6, 0);
                                    }
                                    else if (MsgDI[3] == 0x09)
                                    {
                                        FormatDataOfElectricalEnergy3Byte(inputdata_hex, 14, "电表有功常数 :", " imp/kWh", 1);
                                    }

                                    textBox1.Text +=(sTmp);

                                    break;

                                case 0x05:
                                    switch (MsgDI[3])
                                    {
                                        case 0x01:
                                            textBox1.Text +=("电表运行状态字 1 ");
                                            // 状态字表示 硬遥信实时状态：
                                            if ((inputdata_hex[14] == 0x00) && ((inputdata_hex[15] & 0x01) == 0x01))
                                            {
                                                textBox1.Text +=("硬遥信1 当前状态： 合");
                                            }
                                            if ((inputdata_hex[14] == 0x00) && ((inputdata_hex[15] & 0x01) == 0x00))
                                            {
                                                textBox1.Text +=("硬遥信1 当前状态： 分");
                                            }
                                            if ((inputdata_hex[14] == 0x00) && ((inputdata_hex[15] & 0x02) == 0x02))
                                            {
                                                textBox1.Text +=("硬遥信2 当前状态： 合");
                                            }
                                            if ((inputdata_hex[14] == 0x00) && ((inputdata_hex[15] & 0x02) == 0x00))
                                            {
                                                textBox1.Text +=("硬遥信2 当前状态： 分");
                                            }
                                            break;

                                        case 0x08:
                                            textBox1.Text +=("应答故障和复电信息") + "\r\n";
                                            if (inputdata_hex[14] == 1) //0->无故障   1->有故障
                                            {
                                                textBox1.Text +=("故障标志： 1  有故障 ") + "\r\n";
                                            }
                                            else
                                            {
                                                textBox1.Text +=("故障标志： 0  无故障 ") + "\r\n";
                                            }

                                            ///BCD码 
                                            int tmpVal = 0;
                                            tmpVal = BCD2BYTE(inputdata_hex[15]);
                                            string sTmp = "告警和故障剩余次数：" + tmpVal.ToString() + " 次";
                                            textBox1.Text +=(sTmp) +"\r\n";

                                            if (inputdata_hex[16] == 1) //0->无复电   1->有复电
                                            {
                                                textBox1.Text +=("复电标志： 1  有复电 ") + "\r\n";
                                            }
                                            else
                                            {
                                                textBox1.Text +=("复电标志： 0  无复电 ") + "\r\n";
                                            }

                                            break;

                                        case 0x09:    // 04000509
                                            sTmp = "有事件发生，主动上送 " + inputdata_hex[14].ToString();
                                            textBox1.Text +=(sTmp) + "\r\n";
                                            break;

                                        case 0xFD:    // 040005FD /// C = 0x81 有效？
                                            //从站回复 复电信息
                                            ///复电发生的时间
                                            ///年 月 日 时 分 秒
                                            byte YY = 0; //年
                                            byte MM = 0;
                                            byte DD = 0;
                                            byte hh = 0;
                                            byte mm = 0;
                                            byte ss = 0;

                                            YY = BCD2BYTE((byte)(inputdata_hex[19]));
                                            MM = BCD2BYTE((byte)(inputdata_hex[18]));
                                            DD = BCD2BYTE((byte)(inputdata_hex[17]));
                                            hh = BCD2BYTE((byte)(inputdata_hex[16]));
                                            mm = BCD2BYTE((byte)(inputdata_hex[15]));
                                            ss = BCD2BYTE((byte)(inputdata_hex[14]));

                                            sTmp = "复电的时间：" + "20" + YY.ToString() + "年" + MM.ToString() + "月" + DD.ToString() + "日" + hh.ToString() + "时" + mm.ToString() + "分" + ss.ToString() + "秒";
                                            textBox1.Text +=(sTmp) + "\r\n";
                                            break;

                                        case 0xFE:  // 040005FE /// C = 0x81 有效？

                                            textBox1.Text +=("故障具体事件信息 ") + "\r\n";
                                            break;

                                    }
                                    break;

                            }
                            break;

                        case 0x09:
                            textBox1.Text +=("主站设置阈值") + "\r\n";
                            break;

                        case 0x10:
                            if (MsgDI[3] == 0x00)
                            {
                                textBox1.Text +=("主站设置 硬遥信1防抖参数") + "\r\n";
                            }
                            if (MsgDI[3] == 0x01)
                            {
                                textBox1.Text +=("主站设置 硬遥信2防抖参数") + "\r\n";
                            }
                            break;
                    }
                    break;

                case 0x05:  //冻结数据
                    if (MsgDI[1] == 0x04 || MsgDI[1] == 0x08)
                    {
                        switch (MsgDI[2])
                        {

                            default:
                                if (MsgDI[1] != 0x08)
                                {
                                    sTmp = "上" + MsgDI[3].ToString() + "次" + "冻结时间";
                                    textBox1.Text +=(sTmp);
                                    sTmp += "\r\n";

                                    textBox1.Text += sTmp;
                                }
                                else
                                {
                                    switch (MsgDI[3])
                                    {
                                        case 0x01:
                                            sTmp = "15分钟冻结数据 ";
                                            break;

                                        case 0x02:
                                            sTmp = "小时冻结数据 ";
                                            break;

                                        case 0x03:
                                            sTmp = "每日冻结数据 ";
                                            break;
                                    }

                                    textBox1.Text += (sTmp) + "\r\n";

                                }

                                /// 整点冻结时间
                                sTmp = null;
                                ///冻结发生的时间
                                ///年 月 日 时 分 
                                byte YY = 0; //年
                                byte MM = 0;
                                byte DD = 0;
                                byte hh = 0;
                                byte mm = 0;

                                YY = BCD2BYTE((byte)(inputdata_hex[18]));
                                MM = BCD2BYTE((byte)(inputdata_hex[17]));
                                DD = BCD2BYTE((byte)(inputdata_hex[16]));
                                hh = BCD2BYTE((byte)(inputdata_hex[15]));
                                mm = BCD2BYTE((byte)(inputdata_hex[14]));

                                sTmp = "冻结发生的时间：" + "20" + YY.ToString() + "年" + MM.ToString() + "月" + DD.ToString() + "日" + hh.ToString() + "时" + mm.ToString() + "分";

                                textBox1.Text += sTmp + "\r\n";


                                FormatData0fVariable2Byte(inputdata_hex, 19, "A相电压", "V", 10);
                                FormatData0fVariable2Byte(inputdata_hex, 21, "B相电压", "V", 10);
                                FormatData0fVariable2Byte(inputdata_hex, 23, "C相电压", "V", 10);

                                FormatDataOfElectricalEnergy3Byte(inputdata_hex, 25, "A相电流", "A", 1000 * 20);  /// 数据缩小 20 倍,
                                FormatDataOfElectricalEnergy3Byte(inputdata_hex, 28, "B相电流", "A", 1000 * 20);
                                FormatDataOfElectricalEnergy3Byte(inputdata_hex, 31, "C相电流", "A", 1000 * 20);

                                FormatDataOfElectricalEnergy3Byte(inputdata_hex, 34, "瞬时总有功功率", " kW", 10000 * 20);
                                FormatDataOfElectricalEnergy3Byte(inputdata_hex, 37, "瞬时A相有功功率", " kW", 10000 * 20);
                                FormatDataOfElectricalEnergy3Byte(inputdata_hex, 40, "瞬时B相有功功率", " kW", 10000 * 20);
                                FormatDataOfElectricalEnergy3Byte(inputdata_hex, 43, "瞬时C相有功功率", " kW", 10000 * 20);

                                FormatDataOfElectricalEnergy3Byte(inputdata_hex, 46, "瞬时总无功功率", " kW", 10000 * 20);
                                FormatDataOfElectricalEnergy3Byte(inputdata_hex, 49, "瞬时A相无功功率", " kW", 10000 * 20);
                                FormatDataOfElectricalEnergy3Byte(inputdata_hex, 52, "瞬时B相无功功率", " kW", 10000 * 20);
                                FormatDataOfElectricalEnergy3Byte(inputdata_hex, 55, "瞬时C相无功功率", " kW", 10000 * 20);

                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 58, "(当前)正向有功总电能", " kWh ", 111);
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 62, "(当前)反向有功总电能", " kWh ", 111);

                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 66, "(当前)组合无功1总电能", " kvarh ", 111);
                                FormatDataOfElectricalEnergy4Byte(inputdata_hex, 70, "(当前)组合无功2总电能", " kvarh ", 111);


                                break;
                        }
                    }
                    break;

                case 0x07:
                    if ((MsgDI[1] == 0x00) && (MsgDI[2] == 0x00) && (MsgDI[3] == 0x01))
                    {
                        if ((inputdata_hex[14] == 0x02) && (inputdata_hex[15] == 0x05))
                        {
                            textBox1.Text += "回复主站查询：电压 电流 功率" + "\r\n";
                            FormatDataOfElectricalEnergy3Byte(inputdata_hex, 16, "A 相电压  ", " V ", 1000);
                            FormatDataOfElectricalEnergy3Byte(inputdata_hex, 19, "B 相电压  ", " V ", 1000);
                            FormatDataOfElectricalEnergy3Byte(inputdata_hex, 22, "C 相电压  ", " V ", 1000);

                            FormatDataOfElectricalEnergy4Byte(inputdata_hex, 25, "A 相电流	", " A", 10000);
                            FormatDataOfElectricalEnergy4Byte(inputdata_hex, 29, "B 相电流	", " A", 10000);
                            FormatDataOfElectricalEnergy4Byte(inputdata_hex, 33, "C 相电流	", " A", 10000);

                            FormatDataOfElectricalEnergy3Byte(inputdata_hex, 37, "A 相功率因数 ", " ", 100000);
                            FormatDataOfElectricalEnergy3Byte(inputdata_hex, 40, "B 相功率因数 ", "	", 100000);
                            FormatDataOfElectricalEnergy3Byte(inputdata_hex, 43, "C 相功率因数 ", " ", 100000);

                        }
                        if ((inputdata_hex[14] == 0x10) && (inputdata_hex[15] == 0x05))
                        {
                            textBox1.Text += "回复主站查询：全数据 " + "\r\n";

                            FormatDataOfElectricalEnergy3Byte(inputdata_hex, 16, "A 相电压	", " V ", 1000);
                            FormatDataOfElectricalEnergy3Byte(inputdata_hex, 19, "B 相电压	", " V ", 1000);
                            FormatDataOfElectricalEnergy3Byte(inputdata_hex, 22, "C 相电压	", " V ", 1000);

                            FormatDataOfElectricalEnergy4Byte(inputdata_hex, 25, "A 相电流	", " A", 10000 * 20);
                            FormatDataOfElectricalEnergy4Byte(inputdata_hex, 29, "B 相电流	", " A", 10000 * 20);
                            FormatDataOfElectricalEnergy4Byte(inputdata_hex, 33, "C 相电流	", " A", 10000 * 20);

                            FormatDataOfElectricalEnergy3Byte(inputdata_hex, 37, "A 相功率因数	", "      ", 100000);
                            FormatDataOfElectricalEnergy3Byte(inputdata_hex, 40, "B 相功率因数	", "	  ", 100000);
                            FormatDataOfElectricalEnergy3Byte(inputdata_hex, 43, "C 相功率因数	", "      ", 100000);

                            FormatDataOfElectricalEnergy4Byte(inputdata_hex, 46, "总有功功率	", " kW", 1000000 * 20);
                            FormatDataOfElectricalEnergy4Byte(inputdata_hex, 50, "A 相有功功率	", " kW", 1000000 * 20);
                            FormatDataOfElectricalEnergy4Byte(inputdata_hex, 54, "B 相有功功率	", " kW", 1000000 * 20);
                            FormatDataOfElectricalEnergy4Byte(inputdata_hex, 58, "C 相有功功率	", " kW", 1000000 * 20);


                            FormatDataOfElectricalEnergy4Byte(inputdata_hex, 62, "总无功功率	", " kvar", 1000000 * 20);
                            FormatDataOfElectricalEnergy4Byte(inputdata_hex, 66, "A 相无功功率	", " kvar", 1000000 * 20);
                            FormatDataOfElectricalEnergy4Byte(inputdata_hex, 70, "B 相无功功率	", " kvar", 1000000 * 20);
                            FormatDataOfElectricalEnergy4Byte(inputdata_hex, 74, "C 相无功功率	", " kvar", 1000000 * 20);


                            FormatDataOfElectricalEnergy4Byte(inputdata_hex, 78, "总视在功率	", " kva", 1000000 * 20);
                            FormatDataOfElectricalEnergy4Byte(inputdata_hex, 82, "A 相视在功率	", " kva", 1000000 * 20);
                            FormatDataOfElectricalEnergy4Byte(inputdata_hex, 86, "B 相视在功率	", " kva", 1000000 * 20);
                            FormatDataOfElectricalEnergy4Byte(inputdata_hex, 90, "C 相视在功率	", " kva", 1000000 * 20);


                            FormatDataOfElectricalEnergy4Byte(inputdata_hex, 94, "合相电流	", " A", 10000);
                            FormatDataOfElectricalEnergy4Byte(inputdata_hex, 98, "零线电流	", " A", 10000 * 20);

                            textBox1.Text += "40 bytes 保留 " + "\r\n";
                        }
                    }
                    break;

                case 0x08:
                    if ((MsgDI[1] == 0x00) && (MsgDI[2] == 0x00) && (MsgDI[3] == 0xFF))
                    {
                        textBox1.Text += "topo 底噪实时数据： " + "\r\n";

                        FormatData0fVariable2Byte(inputdata_hex, 14, "A相底噪 ", " ", 1);
                        FormatData0fVariable2Byte(inputdata_hex, 16, "B相底噪 ", " ", 1);
                        FormatData0fVariable2Byte(inputdata_hex, 18, "C相底噪 ", " ", 1);

                    }

                    break;
            }
        }

        private void RecErrAnswerReadDeal()//0xD1 LTU 回复读数据 异常应答
        {
            textBox1.Text += "应答异常： " + "\r\n";
        }
        private void DoAddrSend()    //0x13 请求读电能表通信地址
        {
            this.txt_CtrlItem.Text = "读通信地址";
            textBox1.Text += "请求读电能表通信地址 " + "\r\n";
        }

        private void RecAddrSend() ///0x93 从站应答电能表通信地址
        {
            this.txt_CtrlItem.Text = "应答通信地址";
            textBox1.Text += " 从站应答电能表通信地址 " + "\r\n";

            byte[] meterid = new byte[6];
            for (int i = 0; i < 6; i++)
            {
                meterid[5 - i] = inputdata_hex[14 + i];
            }
            sTmp = "当前设备表号：" + bytesToHexString(meterid, 6, 0);
            textBox1.Text += sTmp + "\r\n";

        }

        private void DoDataSet() //0x14 写数据
        {
            this.txt_CtrlItem.Text = "写数据";
            textBox1.Text += "控制末端拓扑识别 " + "\r\n";

            byte[] bArr_PassWord = new byte[4];
            byte[] bArr_Operator = new byte[4];

            for (int i = 0; i < 4; i++)
            {
                bArr_PassWord[3 - i] = inputdata_hex[i + 14];
                bArr_Operator[3 - i] = inputdata_hex[i + 18];
            }

            sTmp = "密码：       ";
            for (int i = 0; i < 4; i++)
            {
                sTmp += bArr_PassWord[i].ToString("X2");
            }
            textBox1.Text += sTmp + "\r\n";


            sTmp = "操作者代码： ";
            for (int i = 0; i < 4; i++)
            {
                sTmp += bArr_Operator[i].ToString("X2");
            }
            textBox1.Text += sTmp + "\r\n";

            textBox1.Text += "当前模式，收到本帧后就开始发送topo特征波形" + "\r\n";

        }

        private void RecDataSet() //0x94,0xB4
        {
            this.txt_CtrlItem.Text = "LTU应答透传数据";
            textBox1.Text +=("LTU应答透传数据 ");
            string sTemp = " ";
            string ssTmp = " ";
            for (int i = 0; i < inputdata_hex[9]-5; i++)
            {
                ssTmp += inputdata_hex[16 + i].ToString("X2") + " ";
            }

            textBox1.Text = ssTmp + "\r\n";
        }

        private void RecErrAnswerDataSet() ///0xD4 应答写数据 异常报文
        {
            this.txt_CtrlItem.Text = "应答写数据";
            textBox1.Text += "回复应答写数据，异常报文" + "\r\n";
        }


        private void DoReadSetAddr()/// c = 0x15 写通信地址
        {
            this.txt_CtrlItem.Text = "写通信地址";
            textBox1.Text += "设置某从站的通信地址，仅支持点对点通信 " + "\r\n";
            byte[] newSetMeterID = new byte[6];

            for (int i = 0; i < 6; i++)
            {
                newSetMeterID[5 - i] = BYTE2BCD((byte)(inputdata_hex[i + 10]));
            }

            string sTmp = "新设置的表号为：";

            for (int i = 0; i < 6; i++)
            {
                sTmp += newSetMeterID[i].ToString("X2");
            }

            textBox1.Text += sTmp + "\r\n";
        }

        private void RecReadSetAddr()/// c = 0x95 应答写通信地址
        {
            this.txt_CtrlItem.Text = "应答写通信地址";
            textBox1.Text += "应答写通信地址 " + "\r\n";
            textBox1.Text += "从站应答电能表通信地址 " + "\r\n";

            byte[] meterid = new byte[6];
            for (int i = 0; i < 6; i++)
            {
                meterid[5 - i] = inputdata_hex[14 + i];
            }
            sTmp = "当前设备表号：" + bytesToHexString(meterid, 6, 0);
            textBox1.Text += sTmp + "\r\n";
        }



        private void DoMeterZeroClear() /// 0x1A 清零
        {
            this.txt_CtrlItem.Text = "电表清零";
            textBox1.Text += "电表清零 " + "\r\n";

            byte[] bArr_PassWord = new byte[4];
            byte[] bArr_Operator = new byte[4];

            for (int i = 0; i < 4; i++)
            {
                bArr_PassWord[3 - i] = inputdata_hex[i + 14];
                bArr_Operator[3 - i] = inputdata_hex[i + 18];
            }

            sTmp = "密码：       ";
            for (int i = 0; i < 4; i++)
            {
                sTmp += bArr_PassWord[i].ToString("X2");
            }
            textBox1.Text += sTmp + "\r\n";

            sTmp = "操作者代码： ";
            for (int i = 0; i < 4; i++)
            {
                sTmp += bArr_Operator[i].ToString("X2");
            }
            textBox1.Text += sTmp + "\r\n";

        }

        private void RecMeterZeroClear() /// 0x9A 清零
        {
            this.txt_CtrlItem.Text = "应答主站清零";
            textBox1.Text += " 应答主站清零 " + "\r\n";
        }

        private void RecErrAnswerMeterZeroClear()///0xDA 清零异常应答帧
        {
            this.txt_CtrlItem.Text = "应答主站清零";
            textBox1.Text += " 应答主站清零 应答 异常" + "\r\n";

        }

        private void DoSetValueLoad()   ///0x1D  定值下装
        {
            textBox1.Text += " 装置定值下装" + "\r\n";

            MessageBox.Show("此处的定值下装与前面写数据功能一至，写数据中定值下装用于出厂调试，此处的定值下装用于 TTU 定值远程配置");
            ///具体数据项 DI 分项
            ///

        }

        private void RecSetValueLoad()   ///0x9D  应答定值下装
        {
            this.txt_CtrlItem.Text = "应答定值下装";
        }

        private void DoTpDataDel()  /// 0x1E  topo 相关
        {
            this.txt_CtrlItem.Text = "拓扑识别";

            if ((inputdata_hex[10] == 0) && (inputdata_hex[11] == 0) && (inputdata_hex[12] == 0))
            {
                switch (inputdata_hex[13])
                {
                    case 0x01:
                        textBox1.Text +=("主站查询设备类型");
                        break;

                    case 0x02:
                        textBox1.Text +=("主站查询节点拓扑信息");
                        break;

                    case 0x03:
                        textBox1.Text +=("主站下发节点拓扑信息清零");
                        break;

                    case 0x04:
                        textBox1.Text +=("收到节点拓扑主动上送确认帧，清除主动上送");
                        break;

                    case 0x05:
                        textBox1.Text +=("广播清拓扑识别结果，设置开窗时间");

                        string sTmp = "开窗时间: " + inputdata_hex[14].ToString() + " 秒";
                        textBox1.Text +=(sTmp);

                        break;

                    case 0x06:
                        textBox1.Text +=("主站查询设置层级");
                        break;

                }
            }
        }


        private void RecTpDataDel()
        {
            ///年 月 日 时 分 秒
            byte YY = 0; //年
            byte MM = 0;
            byte DD = 0;
            byte hh = 0;
            byte mm = 0;
            byte ss = 0;

            this.txt_CtrlItem.Text = "拓扑识别";

            switch (MsgDI[0])
            {
                case 0x01:      //节点末端
                    if (inputdata_hex[14] == 0x00)
                    {
                        textBox1.Text +=("此设备为 末端");
                    }
                    else if (inputdata_hex[14] == 0x01)
                    {
                        textBox1.Text +=("此设备为 节点");
                    }
                    break;

                case 0x02:
                    textBox1.Text +=("返回的拓扑识别关系");
                    switch (inputdata_hex[14])
                    {
                        case 0x01:
                            textBox1.Text +=("本次识别相别： A 相 ");
                            break;

                        case 0x02:
                            textBox1.Text +=("本次识别相别： B 相 ");
                            break;

                        case 0x03:
                            textBox1.Text +=("本次识别相别： C 相 ");
                            break;
                    }

                    switch (inputdata_hex[15])
                    {
                        case 0x00:
                            sTmp = "拓扑发送序列号： " + inputdata_hex[15].ToString() + " 0xAAE9";

                            break;

                        case 0x01:
                            sTmp = "拓扑发送序列号： " + inputdata_hex[15].ToString() + " 0xD577";

                            break;

                        case 0x02:
                            sTmp = "拓扑发送序列号： " + inputdata_hex[15].ToString() + " 0xCC95";

                            break;

                        case 0x03:
                            sTmp = "拓扑发送序列号： " + inputdata_hex[15].ToString() + " 0xB36Be";

                            break;

                        default:
                            break;
                    }
                    textBox1.Text +=(sTmp);

                    ulong ResTemp = ((ulong)(inputdata_hex[16] << 8 | inputdata_hex[17]));
                    sTmp = "Rec 识别结果：  0x" + ResTemp.ToString("X4");
                    textBox1.Text +=(sTmp);

                    if (inputdata_hex[18] == 0x00)
                    {
                        sTmp = "设备供电状态：单相供电";
                    }
                    else if (inputdata_hex[18] == 0x01)
                    {
                        sTmp = "设备供电状态：三相供电";
                    }
                    else
                    {
                        sTmp = " ";
                    }
                    textBox1.Text +=(sTmp);

                    ///+2 位备用
                    Byte SS_Num = 21;
                    ///识别时间：
                    YY = BCD2BYTE((byte)(inputdata_hex[SS_Num]));
                    MM = BCD2BYTE((byte)(inputdata_hex[SS_Num + 1]));
                    DD = BCD2BYTE((byte)(inputdata_hex[SS_Num + 2]));
                    hh = BCD2BYTE((byte)(inputdata_hex[SS_Num + 3]));
                    mm = BCD2BYTE((byte)(inputdata_hex[SS_Num + 4]));
                    ss = BCD2BYTE((byte)(inputdata_hex[SS_Num + 5]));

                    sTmp = "识别时间：" + "20" + YY.ToString() + "年" + MM.ToString() + "月" + DD.ToString() + "日" + hh.ToString() + "时" + mm.ToString() + "分" + ss.ToString() + "秒";
                    textBox1.Text +=(sTmp);

                    break;

                case 0x03:
                    textBox1.Text +=("节点拓扑信息清零 ");
                    break;

                case 0x04:
                    textBox1.Text +=("收到节点拓扑识别主动上送确认帧，清除主动上送 ");
                    break;

                case 0x05:
                    textBox1.Text +=("广播清拓扑识别信息+开窗时间 ");
                    sTmp = "开窗时间:  " + inputdata_hex[14].ToString() + "  秒  ";
                    textBox1.Text +=(sTmp);
                    break;

                case 0x06:
                    textBox1.Text +=("查层级 ");
                    sTmp = "当前层级： " + inputdata_hex[14].ToString();
                    textBox1.Text +=(sTmp);
                    break;

                case 0x08:
                    ///当前设备的底噪数据分析：
                    textBox1.Text +=(" 当前设备的底噪 ");
                    if (MsgDI[2] == 0x00)
                    {
                        sTmp = " A 相";
                    }
                    else if (MsgDI[2] == 0x01)
                    {
                        sTmp = " B 相";
                    }
                    else if (MsgDI[2] == 0x02)
                    {
                        sTmp = " C 相";
                    }
                    else
                    {
                        textBox1.Text +=(" 当前设备 相别异常！！ ");
                    }

                    if (MsgDI[3] == 0x01)
                    {
                        sTmp += " 0 - 50";
                    }
                    else if (MsgDI[3] == 0x02)
                    {
                        sTmp += " 51 - 100";
                    }
                    else if (MsgDI[3] == 0x03)
                    {
                        sTmp += " 101 - 150";
                    }
                    else if (MsgDI[3] == 0x04)
                    {
                        sTmp += " 151 - 200";
                    }
                    else if (MsgDI[3] == 0x05)
                    {
                        sTmp += " 201 - 250";
                    }
                    else if (MsgDI[3] == 0x06)
                    {
                        sTmp += " 251 - 288";
                    }
                    else
                    {
                        textBox1.Text +=(" 当前设备 底噪点异常！ ");
                    }

                    textBox1.Text +=(sTmp);

                    ///报文数据处理


                    break;

                case 0x0A:
                    textBox1.Text +=("查询设备运行次数");

                    FormatDataOfElectricalEnergy4Byte(inputdata_hex, 14, " DMA 运行次数 ", "  ", 1);
                    FormatDataOfElectricalEnergy4Byte(inputdata_hex, 18, " 60ms DFT 运行次数 ", "  ", 1);
                    FormatDataOfElectricalEnergy4Byte(inputdata_hex, 22, " 600ms 序列判定 运行次数 ", "  ", 1);

                    sTmp = " adc 初始化次数：" + inputdata_hex[22].ToString() + "  ";
                    textBox1.Text +=(sTmp);

                    break;


                default:
                    textBox1.Text +=("报文异常");
                    break;
            }
        }



        private void DoRemoteUpgrade() //0x0F  远程升级
        {
            this.txt_CtrlItem.Text = "远程升级";

            if ((MsgDI[0] == 0x0F) && (MsgDI[2] == 0x0F) && (MsgDI[1] == 0x0F))
            {
                switch (MsgDI[3])
                {
                    case 0x01:
                        textBox1.Text +=("主站升级数据发送请求");

                        ulong FileSize = 0;
                        byte[] bArr_FileSizeTmp = new byte[4];
                        for (int i = 0; i < 4; i++)
                        {
                            bArr_FileSizeTmp[3 - i] = inputdata_hex[i + 22];
                        }
                        for (int i = 0; i < 4; i++)
                        {
                            FileSize = FileSize << 8 | bArr_FileSizeTmp[i];
                        }
                        string sTmp = "总文件大小 ：" + FileSize.ToString() + "(byte)";
                        textBox1.Text +=(sTmp);

                        uint AllFrameNum = 0;
                        byte[] bArr_AllFrameNumTmp = new byte[2];
                        for (int i = 0; i < 2; i++)
                        {
                            bArr_AllFrameNumTmp[1 - i] = inputdata_hex[i + 26];
                        }
                        for (int i = 0; i < 2; i++)
                        {
                            AllFrameNum = AllFrameNum << 8 | bArr_AllFrameNumTmp[i];
                        }
                        sTmp = "总帧数： " + AllFrameNum.ToString();
                        textBox1.Text +=(sTmp);


                        uint FileCRC16Num = 0;
                        byte[] bArr_FileCRC16NumTmp = new byte[2];
                        for (int i = 0; i < 2; i++)
                        {
                            bArr_FileCRC16NumTmp[1 - i] = inputdata_hex[i + 28];
                        }
                        for (int i = 0; i < 2; i++)
                        {
                            FileCRC16Num = FileCRC16Num << 8 | bArr_FileCRC16NumTmp[i];
                        }
                        sTmp = "文件CRC16校验码：  " + FileCRC16Num.ToString("X2");
                        textBox1.Text +=(sTmp);

                        byte[] bArr_RecAppVer = new byte[8];
                        for (int i = 0; i < 8; i++)
                        {
                            bArr_RecAppVer[7 - i] = inputdata_hex[i + 30];
                        }
                        string RecVer = Encoding.Default.GetString(bArr_RecAppVer);
                        sTmp = "升级版本号：" + RecVer;
                        textBox1.Text +=(sTmp);
                        break;

                    case 0x02:
                        textBox1.Text +=("主站下发的数据帧");
                        ulong FrameNum = 0;
                        byte[] bArr_FrameNumTmp = new byte[2];
                        for (int i = 0; i < 2; i++)
                        {
                            bArr_FrameNumTmp[1 - i] = inputdata_hex[i + 22];
                        }
                        for (int i = 0; i < 2; i++)
                        {
                            FrameNum = FrameNum << 8 | bArr_FrameNumTmp[i];
                        }
                        sTmp = "当前帧号：  " + FrameNum.ToString();
                        textBox1.Text +=(sTmp);

                        sTmp = "本帧数据：  " + "160" + "  固定长度";
                        textBox1.Text +=(sTmp);

                        ulong FrameCRC16Num = 0;
                        byte[] bArr_FrameCRC16NumTmp = new byte[2];
                        for (int i = 0; i < 2; i++)
                        {
                            bArr_FrameCRC16NumTmp[1 - i] = inputdata_hex[i + inputdata_length - 4];
                        }
                        for (int i = 0; i < 2; i++)
                        {
                            FrameCRC16Num = FrameCRC16Num << 8 | bArr_FrameCRC16NumTmp[i];
                        }
                        sTmp = "本帧数据CRC：  " + FrameCRC16Num.ToString("X2");
                        textBox1.Text +=(sTmp);

                        break;

                    case 0x03:
                        textBox1.Text +=("主站命令升级帧");
                        if (inputdata_hex[22] == 0x55)
                        {
                            textBox1.Text +=("0x55  确认立刻升级");
                        }
                        else if (inputdata_hex[22] == 0xAA)
                        {
                            textBox1.Text +=("0xAA  放弃升级");
                        }
                        else
                        {
                            textBox1.Text +=(" 无此结果  ");
                        }
                        break;

                    case 0x04:
                        textBox1.Text +=("主站查询现在运行版本号");
                        break;

                    case 0x05:
                        textBox1.Text +=("主站查询接收位图");
                        break;

                    default:
                        textBox1.Text +=("报文异常");
                        break;
                }

            }
            else
            {
                textBox1.Text +=("报文异常");
            }

        }

        private void RecRemoteUpgrade() //0x9F 应答远程升级 
        {
            this.txt_CtrlItem.Text = "远程升级";

            if ((MsgDI[0] == 0x0F) && (MsgDI[2] == 0x0F) && (MsgDI[1] == 0x0F))
            {
                switch (MsgDI[3])
                {
                    case 0x01:
                        textBox1.Text +=("从站是否开始升级应答");
                        break;

                    case 0x02:
                        textBox1.Text +=("从站下发的数据帧");
                        break;

                    case 0x03:
                        textBox1.Text +=("从站命令升级帧");
                        break;

                    case 0x04:
                        textBox1.Text +=("从站查询版本号");
                        break;

                    case 0x05:
                        textBox1.Text +=("从站查询接收位图");
                        break;

                    default:
                        textBox1.Text +=("报文异常");
                        break;
                }

            }
            else
            {
                textBox1.Text +=("报文异常");
            }

        }


        private void btn_Clear_Click(object sender, EventArgs e)
        {
            ClearShowMsg();
        }

        /// <summary>
        /// 清除显示框内数据
        /// </summary>
        /// <returns></returns>
        private void ClearShowMsg()
        {
            txt_Input.Text = " ";
            txt_MeterID.Text = " ";
            txt_CtrlItem.Text = " ";
            txt_CtrlNum.Text = " ";
            txt_MsgDataLength.Text = " ";
            txt_MsgDI.Text = " ";
            txt_CS.Text = " ";

            lb_Item.Items.Clear();

            textBox1.Text = " ";
        }

        private void lb_Item_DrawItem(object sender, DrawItemEventArgs e)
        {
            e.DrawBackground();
            e.DrawFocusRectangle();
            e.Graphics.DrawString(lb_Item.Items[e.Index].ToString(), e.Font, new SolidBrush(Color.Black), e.Bounds);
        }

        private void btn_SendMsgChange_Click(object sender, EventArgs e)
        {
            ////关闭 当前 窗口 （最小化）
            //this.Hide();

            ////打开发送窗口;
            Output output = new Output();
            output.Show();

            //打开test 窗口：
            NewChoose test = new NewChoose();
            test.Show();

        }


        /// <summary>
        /// 确认按键按下
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <returns></returns>
        private void btnInput_Click(object sender, EventArgs e)
        {
            //清除 lb_Item item
            lb_Item.Items.Clear();
            textBox1.Text = " ";

            ///报文 CS 校验和
            byte CheckSumNum = 0;

            bool input_enable = false;

            ///-----------------------------------------------    
            int i = 0;
            inputdata_length = 0;
            ///test 
            if (this.txt_Input.TextLength > 0)
            {
                string Content = this.txt_Input.Text.Replace(" ", "");//获取去除空格后的字符内容   
                int SpaceCount = Content.Length / 2;
                int StartIndex = 2;
                for (i = 0; i < SpaceCount; i++)
                {
                    Content = Content.Insert(StartIndex, " ");
                    StartIndex = StartIndex + 3;
                }
                this.txt_Input.Text = Content.TrimEnd().ToUpper();

                this.txt_Input.SelectionStart = this.txt_Input.Text.Length;


                byte[] data = new ASCIIEncoding().GetBytes(this.txt_Input.Text.Trim());

                for (i = 0; i < (data.Length); i += 3)
                {
                    if ((data[i] >= 0x30 && data[i] <= 0x39) && (data[i + 1] >= 0x30 && data[i + 1] <= 0x39))
                    {
                        inputdata_hex[inputdata_length] = (byte)(((data[i] - 0x30) << 4 & 0xF0) | ((data[i + 1] - 0x30) & 0x0F));
                        inputdata_length++;

                        continue;
                    }

                    if ((data[i] >= 0x41 && data[i] <= 0x46))
                    {
                        data[i] -= 0x37;
                    }
                    else if ((data[i] >= 0x61 && data[i] <= 0x66))
                    {
                        data[i] -= 0x57;
                    }

                    if ((data[i + 1] >= 0x41 && data[i + 1] <= 0x46))
                    {
                        data[i + 1] -= 0x37;
                    }
                    else if ((data[i + 1] >= 0x61 && data[i + 1] <= 0x66))
                    {
                        data[i + 1] -= 0x57;
                    }

                    inputdata_hex[inputdata_length] = (byte)(((data[i]) << 4 & 0xF0) | ((data[i + 1]) & 0x0F));
                    inputdata_length++;

                }
            }

            if (inputdata_length > 10)
            {
                ///计算接收到的数组报文 CS 校验和
                CheckSumNum = CheckSum(inputdata_hex, inputdata_length);

                ///报文数组符合645规约结构
                if ((inputdata_hex[0] == 0x68) && (inputdata_hex[7] == 0x68) && (inputdata_hex[inputdata_length - 2] == CheckSumNum))
                {
                    input_enable = true;
                }
                else
                {
                    if (inputdata_hex[0] != 0x68)
                    {
                        MessageBox.Show("输入报文有误，报文头数据错误");
                        this.txt_Input.Text = null;
                    }
                    else
                    {
                        MessageBox.Show("输入报文有误，CS累加校验和异常");
                        this.txt_Input.Text = null;
                    }
                }
            }

            if (input_enable == true)
            {
                ///表地址
                byte[] MeterID = new byte[6];
                for (i = 0; i < 6; i++)
                {
                    MeterID[5 - i] = inputdata_hex[i + 1];
                }
                this.txt_MeterID.Text = bytesToHexString(MeterID, 6, 0);
                //控制码
                this.txt_CtrlNum.Text = bytesToHexString(inputdata_hex, 1, 8);
                //数据域长度
                this.txt_MsgDataLength.Text = bytesToHexString(inputdata_hex, 1, 9);

                // 根据 645 规约 数据域 -33;
                DecodeDataBuf(inputdata_hex, inputdata_hex[9], 10);

                if ((inputdata_hex[9] >= 4) && (inputdata_hex[8] != 0x08) && (inputdata_hex[8] != 0x09))
                {
                    sTmp = "";
                    for (i = 0; i < 4; i++)
                    {
                        MsgDI[3 - i] = ((byte)(inputdata_hex[10 + i])); //反序
                    }
                    for (i = 0; i < 4; i++)
                    {
                        sTmp += MsgDI[i].ToString("X2") + " ";
                    }
                }
                this.txt_MsgDI.Text = sTmp;
                this.txt_CS.Text = bytesToHexString(inputdata_hex, 1, inputdata_length - 2);

                switch (inputdata_hex[8])
                {
                    ///主站发送的相关报文
                    case 0x01://读故障和复电信息
                        DoReadGzFdInfo();
                        break;
                    case 0x02://读掉电状态
                        DoReadDdState();
                        break;
                    case 0x03://终端确认帧
                        DoFaultAck();
                        break;
                    case 0x04: //透传
                        DoPassThrough();
                        break;
                    case 0x08://对时
                        DoReadSetClk();
                        break;
                    case 0x09://掉电主动上报确认帧处理
                        DoDdSendAutoAck();
                        break;
                    case 0x11://读数据
                        DoDataReadDeal();
                        break;
                    case 0x13://读地址
                        DoAddrSend();
                        break;
                    case 0x14://写数据
                        DoDataSet();
                        break;
                    case 0x15://写通信地址
                        DoReadSetAddr();
                        break;
                    case 0x1A://电表清零
                        DoMeterZeroClear();
                        break;
                    case 0x1D://定值下装
                        DoSetValueLoad();
                        break;
                    case 0x1E://节点拓扑
                        DoTpDataDel();
                        break;
                    case 0x0F:
                        DoRemoteUpgrade(); // 远程升级
                        break;

                    /// LTU 回复的报文
                    case 0x81:  //应答 故障和复电信息
                        RecReadGzFdInfo();
                        break;
                    case 0x82://读掉电应答
                        RecReadDdState();
                        break;
                    case 0x83://终端应答终端确认帧
                        RecFaultAck();
                        break;
                    case 0x79:
                        RecYdDdSendAutoAck();
                        break;
                    case 0x89:
                        RecDdSendAutoAck();
                        break;
                    case 0x91://读数据应答
                        RecReadDeal();
                        break;
                    case 0xD1://读数据从站异常应答
                        RecErrAnswerReadDeal();
                        break;
                    case 0x93://从站应答 通信地址
                        RecAddrSend();
                        break;
                    case 0x94:
                    case 0xB4:
                        RecDataSet();
                        break;
                    case 0xD4://应答写数据 异常应答
                        RecErrAnswerDataSet();
                        break;
                    case 0x95://应答写通信地址
                        RecReadSetAddr();
                        break;
                    case 0xD9:  ///故障复电 异常应答
                        RecErrAnswerReadGzFdInfo();
                        break;
                    case 0x9A: //电表清零从站应答帧
                        RecMeterZeroClear();
                        break;
                    case 0xDA://电表清零从站 异常应答帧
                        RecErrAnswerMeterZeroClear();
                        break;
                    case 0x9D:///应答定制下装
                        RecSetValueLoad();
                        break;
                    case 0x9E:///从站回复 节点拓扑识别
                        RecTpDataDel();
                        break;
                    case 0x9F:
                        RecRemoteUpgrade();
                        break;

                    default:
                        break;
                }



            }
        }

        private void lb_Item_SelectedIndexChanged(object sender, EventArgs e)
        {

        }
    }
}
